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 void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
876 static bool spe_func_has_64bit_regs_p (void);
877 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
879 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
880 static unsigned rs6000_hash_constant (rtx);
881 static unsigned toc_hash_function (const void *);
882 static int toc_hash_eq (const void *, const void *);
883 static bool reg_offset_addressing_ok_p (enum machine_mode);
884 static bool virtual_stack_registers_memory_p (rtx);
885 static bool constant_pool_expr_p (rtx);
886 static bool legitimate_small_data_p (enum machine_mode, rtx);
887 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
888 static struct machine_function * rs6000_init_machine_status (void);
889 static bool rs6000_assemble_integer (rtx, unsigned int, int);
890 static bool no_global_regs_above (int, bool);
891 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
892 static void rs6000_assemble_visibility (tree, int);
894 static int rs6000_ra_ever_killed (void);
895 static bool rs6000_attribute_takes_identifier_p (const_tree);
896 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
897 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
898 static bool rs6000_ms_bitfield_layout_p (const_tree);
899 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
900 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
901 static const char *rs6000_mangle_type (const_tree);
902 static void rs6000_set_default_type_attributes (tree);
903 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
904 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
905 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
906 enum machine_mode, bool, bool, bool);
907 static bool rs6000_reg_live_or_pic_offset_p (int);
908 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
909 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
910 static void rs6000_restore_saved_cr (rtx, int);
911 static bool rs6000_output_addr_const_extra (FILE *, rtx);
912 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
913 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
914 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
916 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
917 static bool rs6000_return_in_memory (const_tree, const_tree);
918 static rtx rs6000_function_value (const_tree, const_tree, bool);
919 static void rs6000_file_start (void);
921 static int rs6000_elf_reloc_rw_mask (void);
922 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
923 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
924 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
925 static void rs6000_elf_asm_init_sections (void);
926 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
927 unsigned HOST_WIDE_INT);
928 static void rs6000_elf_encode_section_info (tree, rtx, int)
931 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
932 static void rs6000_alloc_sdmode_stack_slot (void);
933 static void rs6000_instantiate_decls (void);
935 static void rs6000_xcoff_asm_output_anchor (rtx);
936 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
937 static void rs6000_xcoff_asm_init_sections (void);
938 static int rs6000_xcoff_reloc_rw_mask (void);
939 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
940 static section *rs6000_xcoff_select_section (tree, int,
941 unsigned HOST_WIDE_INT);
942 static void rs6000_xcoff_unique_section (tree, int);
943 static section *rs6000_xcoff_select_rtx_section
944 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
945 static const char * rs6000_xcoff_strip_name_encoding (const char *);
946 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
947 static void rs6000_xcoff_file_start (void);
948 static void rs6000_xcoff_file_end (void);
950 static int rs6000_variable_issue (FILE *, int, rtx, int);
951 static int rs6000_register_move_cost (enum machine_mode,
952 reg_class_t, reg_class_t);
953 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
954 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
955 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
956 static int rs6000_debug_address_cost (rtx, bool);
957 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
958 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
959 static void rs6000_sched_init (FILE *, int, int);
960 static bool is_microcoded_insn (rtx);
961 static bool is_nonpipeline_insn (rtx);
962 static bool is_cracked_insn (rtx);
963 static bool is_branch_slot_insn (rtx);
964 static bool is_load_insn (rtx);
965 static rtx get_store_dest (rtx pat);
966 static bool is_store_insn (rtx);
967 static bool set_to_load_agen (rtx,rtx);
968 static bool adjacent_mem_locations (rtx,rtx);
969 static int rs6000_adjust_priority (rtx, int);
970 static int rs6000_issue_rate (void);
971 static bool rs6000_is_costly_dependence (dep_t, int, int);
972 static rtx get_next_active_insn (rtx, rtx);
973 static bool insn_terminates_group_p (rtx , enum group_termination);
974 static bool insn_must_be_first_in_group (rtx);
975 static bool insn_must_be_last_in_group (rtx);
976 static bool is_costly_group (rtx *, rtx);
977 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
978 static int redefine_groups (FILE *, int, rtx, rtx);
979 static int pad_groups (FILE *, int, rtx, rtx);
980 static void rs6000_sched_finish (FILE *, int);
981 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
982 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
983 static int rs6000_use_sched_lookahead (void);
984 static int rs6000_use_sched_lookahead_guard (rtx);
985 static void * rs6000_alloc_sched_context (void);
986 static void rs6000_init_sched_context (void *, bool);
987 static void rs6000_set_sched_context (void *);
988 static void rs6000_free_sched_context (void *);
989 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
990 static tree rs6000_builtin_mask_for_load (void);
991 static tree rs6000_builtin_mul_widen_even (tree);
992 static tree rs6000_builtin_mul_widen_odd (tree);
993 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
994 static tree rs6000_builtin_vec_perm (tree, tree *);
995 static bool rs6000_builtin_support_vector_misalignment (enum
999 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1001 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1003 static void def_builtin (int, const char *, tree, int);
1004 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1005 static void rs6000_init_builtins (void);
1006 static tree rs6000_builtin_decl (unsigned, bool);
1008 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1009 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1010 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1011 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1012 static void altivec_init_builtins (void);
1013 static unsigned builtin_hash_function (const void *);
1014 static int builtin_hash_eq (const void *, const void *);
1015 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1016 enum machine_mode, enum machine_mode,
1017 enum rs6000_builtins, const char *name);
1018 static void rs6000_common_init_builtins (void);
1019 static void rs6000_init_libfuncs (void);
1021 static void paired_init_builtins (void);
1022 static rtx paired_expand_builtin (tree, rtx, bool *);
1023 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1024 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1025 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1027 static void enable_mask_for_builtins (struct builtin_description *, int,
1028 enum rs6000_builtins,
1029 enum rs6000_builtins);
1030 static void spe_init_builtins (void);
1031 static rtx spe_expand_builtin (tree, rtx, bool *);
1032 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1033 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1034 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1035 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1036 static rs6000_stack_t *rs6000_stack_info (void);
1037 static void debug_stack_info (rs6000_stack_t *);
1039 static rtx altivec_expand_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1041 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1042 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1043 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1044 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1045 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1046 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1047 static rtx altivec_expand_vec_set_builtin (tree);
1048 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1049 static int get_element_number (tree, tree);
1050 static void rs6000_option_override (void);
1051 static int rs6000_loop_align_max_skip (rtx);
1052 static int first_altivec_reg_to_save (void);
1053 static unsigned int compute_vrsave_mask (void);
1054 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1055 static void is_altivec_return_reg (rtx, void *);
1056 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1057 int easy_vector_constant (rtx, enum machine_mode);
1058 static rtx rs6000_dwarf_register_span (rtx);
1059 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1060 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1061 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1062 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1063 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1064 static rtx rs6000_delegitimize_address (rtx);
1065 static rtx rs6000_tls_get_addr (void);
1066 static rtx rs6000_got_sym (void);
1067 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1068 static const char *rs6000_get_some_local_dynamic_name (void);
1069 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1070 static rtx rs6000_complex_function_value (enum machine_mode);
1071 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1072 enum machine_mode, const_tree);
1073 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1074 HOST_WIDE_INT, int);
1075 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1078 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1081 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1082 const_tree, HOST_WIDE_INT,
1084 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1085 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1086 static void rs6000_function_arg_advance (cumulative_args_t, enum machine_mode,
1088 static rtx rs6000_function_arg (cumulative_args_t, enum machine_mode,
1090 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1092 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1093 static void setup_incoming_varargs (cumulative_args_t,
1094 enum machine_mode, tree,
1096 static bool rs6000_pass_by_reference (cumulative_args_t, enum machine_mode,
1098 static int rs6000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
1100 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1102 static void macho_branch_islands (void);
1103 static int no_previous_def (tree function_name);
1104 static tree get_prev_label (tree function_name);
1105 static void rs6000_darwin_file_start (void);
1108 static tree rs6000_build_builtin_va_list (void);
1109 static void rs6000_va_start (tree, rtx);
1110 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1111 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1112 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1113 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1114 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1115 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1117 static tree rs6000_stack_protect_fail (void);
1119 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1122 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1125 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1127 = rs6000_legitimize_reload_address;
1129 static bool rs6000_mode_dependent_address_p (const_rtx);
1130 static bool rs6000_mode_dependent_address (const_rtx);
1131 static bool rs6000_debug_mode_dependent_address (const_rtx);
1132 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1133 = rs6000_mode_dependent_address;
1135 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1136 enum machine_mode, rtx);
1137 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1140 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1141 enum machine_mode, rtx)
1142 = rs6000_secondary_reload_class;
1144 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1145 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1147 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1148 = rs6000_preferred_reload_class;
1150 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1153 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1157 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1159 = rs6000_secondary_memory_needed;
1161 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1164 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1168 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1171 = rs6000_cannot_change_mode_class;
1173 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1175 struct secondary_reload_info *);
1177 const int INSN_NOT_AVAILABLE = -1;
1178 static enum machine_mode rs6000_eh_return_filter_mode (void);
1179 static bool rs6000_can_eliminate (const int, const int);
1180 static void rs6000_conditional_register_usage (void);
1181 static void rs6000_trampoline_init (rtx, tree, rtx);
1182 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1183 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1185 /* Hash table stuff for keeping track of TOC entries. */
1187 struct GTY(()) toc_hash_struct
1189 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1190 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1192 enum machine_mode key_mode;
1196 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1198 /* Hash table to keep track of the argument types for builtin functions. */
1200 struct GTY(()) builtin_hash_struct
1203 enum machine_mode mode[4]; /* return value + 3 arguments. */
1204 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1207 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1209 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1210 static void rs6000_function_specific_save (struct cl_target_option *);
1211 static void rs6000_function_specific_restore (struct cl_target_option *);
1212 static void rs6000_function_specific_print (FILE *, int,
1213 struct cl_target_option *);
1214 static bool rs6000_can_inline_p (tree, tree);
1215 static void rs6000_set_current_function (tree);
1218 /* Default register names. */
1219 char rs6000_reg_names[][8] =
1221 "0", "1", "2", "3", "4", "5", "6", "7",
1222 "8", "9", "10", "11", "12", "13", "14", "15",
1223 "16", "17", "18", "19", "20", "21", "22", "23",
1224 "24", "25", "26", "27", "28", "29", "30", "31",
1225 "0", "1", "2", "3", "4", "5", "6", "7",
1226 "8", "9", "10", "11", "12", "13", "14", "15",
1227 "16", "17", "18", "19", "20", "21", "22", "23",
1228 "24", "25", "26", "27", "28", "29", "30", "31",
1229 "mq", "lr", "ctr","ap",
1230 "0", "1", "2", "3", "4", "5", "6", "7",
1232 /* AltiVec registers. */
1233 "0", "1", "2", "3", "4", "5", "6", "7",
1234 "8", "9", "10", "11", "12", "13", "14", "15",
1235 "16", "17", "18", "19", "20", "21", "22", "23",
1236 "24", "25", "26", "27", "28", "29", "30", "31",
1238 /* SPE registers. */
1239 "spe_acc", "spefscr",
1240 /* Soft frame pointer. */
1244 #ifdef TARGET_REGNAMES
1245 static const char alt_reg_names[][8] =
1247 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1248 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1249 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1250 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1251 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1252 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1253 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1254 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1255 "mq", "lr", "ctr", "ap",
1256 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1258 /* AltiVec registers. */
1259 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1260 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1261 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1262 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1264 /* SPE registers. */
1265 "spe_acc", "spefscr",
1266 /* Soft frame pointer. */
1271 /* Table of valid machine attributes. */
1273 static const struct attribute_spec rs6000_attribute_table[] =
1275 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1276 affects_type_identity } */
1277 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1279 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1281 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1283 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1285 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1287 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1288 SUBTARGET_ATTRIBUTE_TABLE,
1290 { NULL, 0, 0, false, false, false, NULL, false }
1293 #ifndef MASK_STRICT_ALIGN
1294 #define MASK_STRICT_ALIGN 0
1296 #ifndef TARGET_PROFILE_KERNEL
1297 #define TARGET_PROFILE_KERNEL 0
1300 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1301 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1303 /* Initialize the GCC target structure. */
1304 #undef TARGET_ATTRIBUTE_TABLE
1305 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1306 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1307 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1308 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1309 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1311 #undef TARGET_ASM_ALIGNED_DI_OP
1312 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1314 /* Default unaligned ops are only provided for ELF. Find the ops needed
1315 for non-ELF systems. */
1316 #ifndef OBJECT_FORMAT_ELF
1318 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1320 #undef TARGET_ASM_UNALIGNED_HI_OP
1321 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1322 #undef TARGET_ASM_UNALIGNED_SI_OP
1323 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1324 #undef TARGET_ASM_UNALIGNED_DI_OP
1325 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1328 #undef TARGET_ASM_UNALIGNED_HI_OP
1329 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1330 #undef TARGET_ASM_UNALIGNED_SI_OP
1331 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1332 #undef TARGET_ASM_UNALIGNED_DI_OP
1333 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1334 #undef TARGET_ASM_ALIGNED_DI_OP
1335 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1339 /* This hook deals with fixups for relocatable code and DI-mode objects
1341 #undef TARGET_ASM_INTEGER
1342 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1344 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
1345 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1346 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1349 #undef TARGET_HAVE_TLS
1350 #define TARGET_HAVE_TLS HAVE_AS_TLS
1352 #undef TARGET_CANNOT_FORCE_CONST_MEM
1353 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1355 #undef TARGET_DELEGITIMIZE_ADDRESS
1356 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1358 #undef TARGET_ASM_FUNCTION_PROLOGUE
1359 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1360 #undef TARGET_ASM_FUNCTION_EPILOGUE
1361 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1363 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1364 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1366 #undef TARGET_LEGITIMIZE_ADDRESS
1367 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1369 #undef TARGET_SCHED_VARIABLE_ISSUE
1370 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1372 #undef TARGET_SCHED_ISSUE_RATE
1373 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1374 #undef TARGET_SCHED_ADJUST_COST
1375 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1376 #undef TARGET_SCHED_ADJUST_PRIORITY
1377 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1378 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1379 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1380 #undef TARGET_SCHED_INIT
1381 #define TARGET_SCHED_INIT rs6000_sched_init
1382 #undef TARGET_SCHED_FINISH
1383 #define TARGET_SCHED_FINISH rs6000_sched_finish
1384 #undef TARGET_SCHED_REORDER
1385 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1386 #undef TARGET_SCHED_REORDER2
1387 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1389 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1390 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1392 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1393 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1395 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1396 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1397 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1398 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1399 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1400 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1401 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1402 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1404 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1405 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1406 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1407 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1408 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1409 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1410 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1411 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1412 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1413 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1414 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1415 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1416 rs6000_builtin_support_vector_misalignment
1417 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1418 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1419 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1420 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1421 rs6000_builtin_vectorization_cost
1422 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1423 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1424 rs6000_preferred_simd_mode
1426 #undef TARGET_INIT_BUILTINS
1427 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1428 #undef TARGET_BUILTIN_DECL
1429 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1431 #undef TARGET_EXPAND_BUILTIN
1432 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1434 #undef TARGET_MANGLE_TYPE
1435 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1437 #undef TARGET_INIT_LIBFUNCS
1438 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1441 #undef TARGET_BINDS_LOCAL_P
1442 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1445 #undef TARGET_MS_BITFIELD_LAYOUT_P
1446 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1448 #undef TARGET_ASM_OUTPUT_MI_THUNK
1449 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1451 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1452 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1454 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1455 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1457 #undef TARGET_INVALID_WITHIN_DOLOOP
1458 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1460 #undef TARGET_REGISTER_MOVE_COST
1461 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1462 #undef TARGET_MEMORY_MOVE_COST
1463 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1464 #undef TARGET_RTX_COSTS
1465 #define TARGET_RTX_COSTS rs6000_rtx_costs
1466 #undef TARGET_ADDRESS_COST
1467 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1469 #undef TARGET_DWARF_REGISTER_SPAN
1470 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1472 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1473 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1475 /* On rs6000, function arguments are promoted, as are function return
1477 #undef TARGET_PROMOTE_FUNCTION_MODE
1478 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1480 #undef TARGET_RETURN_IN_MEMORY
1481 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1483 #undef TARGET_SETUP_INCOMING_VARARGS
1484 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1486 /* Always strict argument naming on rs6000. */
1487 #undef TARGET_STRICT_ARGUMENT_NAMING
1488 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1489 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1490 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1491 #undef TARGET_SPLIT_COMPLEX_ARG
1492 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1493 #undef TARGET_MUST_PASS_IN_STACK
1494 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1495 #undef TARGET_PASS_BY_REFERENCE
1496 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1497 #undef TARGET_ARG_PARTIAL_BYTES
1498 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1499 #undef TARGET_FUNCTION_ARG_ADVANCE
1500 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1501 #undef TARGET_FUNCTION_ARG
1502 #define TARGET_FUNCTION_ARG rs6000_function_arg
1503 #undef TARGET_FUNCTION_ARG_BOUNDARY
1504 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1506 #undef TARGET_BUILD_BUILTIN_VA_LIST
1507 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1509 #undef TARGET_EXPAND_BUILTIN_VA_START
1510 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1512 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1513 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1515 #undef TARGET_EH_RETURN_FILTER_MODE
1516 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1518 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1519 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1521 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1522 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1524 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1525 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1527 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1528 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1530 #undef TARGET_OPTION_OVERRIDE
1531 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1533 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1534 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1535 rs6000_builtin_vectorized_function
1537 #ifndef TARGET_MACHO
1538 #undef TARGET_STACK_PROTECT_FAIL
1539 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1542 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1543 The PowerPC architecture requires only weak consistency among
1544 processors--that is, memory accesses between processors need not be
1545 sequentially consistent and memory accesses among processors can occur
1546 in any order. The ability to order memory accesses weakly provides
1547 opportunities for more efficient use of the system bus. Unless a
1548 dependency exists, the 604e allows read operations to precede store
1550 #undef TARGET_RELAXED_ORDERING
1551 #define TARGET_RELAXED_ORDERING true
1554 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1555 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1558 /* Use a 32-bit anchor range. This leads to sequences like:
1560 addis tmp,anchor,high
1563 where tmp itself acts as an anchor, and can be shared between
1564 accesses to the same 64k page. */
1565 #undef TARGET_MIN_ANCHOR_OFFSET
1566 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1567 #undef TARGET_MAX_ANCHOR_OFFSET
1568 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1569 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1570 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1572 #undef TARGET_BUILTIN_RECIPROCAL
1573 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1575 #undef TARGET_EXPAND_TO_RTL_HOOK
1576 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1578 #undef TARGET_INSTANTIATE_DECLS
1579 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1581 #undef TARGET_SECONDARY_RELOAD
1582 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1584 #undef TARGET_LEGITIMATE_ADDRESS_P
1585 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1587 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1588 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1590 #undef TARGET_CAN_ELIMINATE
1591 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1593 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1594 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1596 #undef TARGET_TRAMPOLINE_INIT
1597 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1599 #undef TARGET_FUNCTION_VALUE
1600 #define TARGET_FUNCTION_VALUE rs6000_function_value
1602 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1603 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1605 #undef TARGET_OPTION_SAVE
1606 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1608 #undef TARGET_OPTION_RESTORE
1609 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1611 #undef TARGET_OPTION_PRINT
1612 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1614 #undef TARGET_CAN_INLINE_P
1615 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1617 #undef TARGET_SET_CURRENT_FUNCTION
1618 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1620 #undef TARGET_LEGITIMATE_CONSTANT_P
1621 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1623 struct gcc_target targetm = TARGET_INITIALIZER;
1626 /* Simplifications for entries below. */
1629 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1630 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1633 /* Some OSs don't support saving the high part of 64-bit registers on context
1634 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1635 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1636 either, the user must explicitly specify them and we won't interfere with
1637 the user's specification. */
1640 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1641 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1642 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1643 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1644 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1645 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1646 | MASK_RECIP_PRECISION)
1649 /* Masks for instructions set at various powerpc ISAs. */
1651 ISA_2_1_MASKS = MASK_MFCRF,
1652 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1653 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1655 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1656 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1657 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1658 server and embedded. */
1659 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1660 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1661 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1663 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1664 altivec is a win so enable it. */
1665 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1666 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1672 const char *const name; /* Canonical processor name. */
1673 const enum processor_type processor; /* Processor type enum value. */
1674 const int target_enable; /* Target flags to enable. */
1677 static struct rs6000_ptt const processor_target_table[] =
1679 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1680 #include "rs6000-cpus.def"
1684 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1688 rs6000_cpu_name_lookup (const char *name)
1694 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1695 if (! strcmp (name, processor_target_table[i].name))
1703 /* Return number of consecutive hard regs needed starting at reg REGNO
1704 to hold something of mode MODE.
1705 This is ordinarily the length in words of a value of mode MODE
1706 but can be less for certain modes in special long registers.
1708 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1709 scalar instructions. The upper 32 bits are only available to the
1712 POWER and PowerPC GPRs hold 32 bits worth;
1713 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1716 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1718 unsigned HOST_WIDE_INT reg_size;
1720 if (FP_REGNO_P (regno))
1721 reg_size = (VECTOR_MEM_VSX_P (mode)
1722 ? UNITS_PER_VSX_WORD
1723 : UNITS_PER_FP_WORD);
1725 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1726 reg_size = UNITS_PER_SPE_WORD;
1728 else if (ALTIVEC_REGNO_P (regno))
1729 reg_size = UNITS_PER_ALTIVEC_WORD;
1731 /* The value returned for SCmode in the E500 double case is 2 for
1732 ABI compatibility; storing an SCmode value in a single register
1733 would require function_arg and rs6000_spe_function_arg to handle
1734 SCmode so as to pass the value correctly in a pair of
1736 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1737 && !DECIMAL_FLOAT_MODE_P (mode))
1738 reg_size = UNITS_PER_FP_WORD;
1741 reg_size = UNITS_PER_WORD;
1743 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1746 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1749 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1751 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1753 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1754 implementations. Don't allow an item to be split between a FP register
1755 and an Altivec register. */
1756 if (VECTOR_MEM_VSX_P (mode))
1758 if (FP_REGNO_P (regno))
1759 return FP_REGNO_P (last_regno);
1761 if (ALTIVEC_REGNO_P (regno))
1762 return ALTIVEC_REGNO_P (last_regno);
1765 /* The GPRs can hold any mode, but values bigger than one register
1766 cannot go past R31. */
1767 if (INT_REGNO_P (regno))
1768 return INT_REGNO_P (last_regno);
1770 /* The float registers (except for VSX vector modes) can only hold floating
1771 modes and DImode. This excludes the 32-bit decimal float mode for
1773 if (FP_REGNO_P (regno))
1775 if (SCALAR_FLOAT_MODE_P (mode)
1776 && (mode != TDmode || (regno % 2) == 0)
1777 && FP_REGNO_P (last_regno))
1780 if (GET_MODE_CLASS (mode) == MODE_INT
1781 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1784 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1785 && PAIRED_VECTOR_MODE (mode))
1791 /* The CR register can only hold CC modes. */
1792 if (CR_REGNO_P (regno))
1793 return GET_MODE_CLASS (mode) == MODE_CC;
1795 if (CA_REGNO_P (regno))
1796 return mode == BImode;
1798 /* AltiVec only in AldyVec registers. */
1799 if (ALTIVEC_REGNO_P (regno))
1800 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1802 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1803 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1806 /* We cannot put TImode anywhere except general register and it must be able
1807 to fit within the register set. In the future, allow TImode in the
1808 Altivec or VSX registers. */
1810 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1813 /* Print interesting facts about registers. */
1815 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1819 for (r = first_regno; r <= last_regno; ++r)
1821 const char *comma = "";
1824 if (first_regno == last_regno)
1825 fprintf (stderr, "%s:\t", reg_name);
1827 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1830 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1831 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1835 fprintf (stderr, ",\n\t");
1840 if (rs6000_hard_regno_nregs[m][r] > 1)
1841 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1842 rs6000_hard_regno_nregs[m][r]);
1844 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1849 if (call_used_regs[r])
1853 fprintf (stderr, ",\n\t");
1858 len += fprintf (stderr, "%s%s", comma, "call-used");
1866 fprintf (stderr, ",\n\t");
1871 len += fprintf (stderr, "%s%s", comma, "fixed");
1877 fprintf (stderr, ",\n\t");
1881 fprintf (stderr, "%sregno = %d\n", comma, r);
1885 #define DEBUG_FMT_D "%-32s= %d\n"
1886 #define DEBUG_FMT_S "%-32s= %s\n"
1888 /* Print various interesting information with -mdebug=reg. */
1890 rs6000_debug_reg_global (void)
1892 static const char *const tf[2] = { "false", "true" };
1893 const char *nl = (const char *)0;
1895 char costly_num[20];
1897 const char *costly_str;
1898 const char *nop_str;
1899 const char *trace_str;
1900 const char *abi_str;
1901 const char *cmodel_str;
1903 /* Map enum rs6000_vector to string. */
1904 static const char *rs6000_debug_vector_unit[] = {
1913 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1914 LAST_VIRTUAL_REGISTER);
1915 rs6000_debug_reg_print (0, 31, "gr");
1916 rs6000_debug_reg_print (32, 63, "fp");
1917 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1920 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1921 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1922 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1923 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1924 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1925 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1926 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1927 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1928 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1932 "d reg_class = %s\n"
1933 "f reg_class = %s\n"
1934 "v reg_class = %s\n"
1935 "wa reg_class = %s\n"
1936 "wd reg_class = %s\n"
1937 "wf reg_class = %s\n"
1938 "ws reg_class = %s\n\n",
1939 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1940 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1941 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1942 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1943 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1944 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1945 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1947 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1948 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1951 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1953 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1954 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1960 if (rs6000_recip_control)
1962 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1964 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1965 if (rs6000_recip_bits[m])
1968 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1970 (RS6000_RECIP_AUTO_RE_P (m)
1972 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1973 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1975 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1978 fputs ("\n", stderr);
1981 if (rs6000_cpu_index >= 0)
1982 fprintf (stderr, DEBUG_FMT_S, "cpu",
1983 processor_target_table[rs6000_cpu_index].name);
1985 if (rs6000_tune_index >= 0)
1986 fprintf (stderr, DEBUG_FMT_S, "tune",
1987 processor_target_table[rs6000_tune_index].name);
1989 switch (rs6000_sched_costly_dep)
1991 case max_dep_latency:
1992 costly_str = "max_dep_latency";
1996 costly_str = "no_dep_costly";
1999 case all_deps_costly:
2000 costly_str = "all_deps_costly";
2003 case true_store_to_load_dep_costly:
2004 costly_str = "true_store_to_load_dep_costly";
2007 case store_to_load_dep_costly:
2008 costly_str = "store_to_load_dep_costly";
2012 costly_str = costly_num;
2013 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2017 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2019 switch (rs6000_sched_insert_nops)
2021 case sched_finish_regroup_exact:
2022 nop_str = "sched_finish_regroup_exact";
2025 case sched_finish_pad_groups:
2026 nop_str = "sched_finish_pad_groups";
2029 case sched_finish_none:
2030 nop_str = "sched_finish_none";
2035 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2039 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2041 switch (rs6000_sdata)
2048 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2052 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2056 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2061 switch (rs6000_traceback)
2063 case traceback_default: trace_str = "default"; break;
2064 case traceback_none: trace_str = "none"; break;
2065 case traceback_part: trace_str = "part"; break;
2066 case traceback_full: trace_str = "full"; break;
2067 default: trace_str = "unknown"; break;
2070 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2072 switch (rs6000_current_cmodel)
2074 case CMODEL_SMALL: cmodel_str = "small"; break;
2075 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2076 case CMODEL_LARGE: cmodel_str = "large"; break;
2077 default: cmodel_str = "unknown"; break;
2080 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2082 switch (rs6000_current_abi)
2084 case ABI_NONE: abi_str = "none"; break;
2085 case ABI_AIX: abi_str = "aix"; break;
2086 case ABI_V4: abi_str = "V4"; break;
2087 case ABI_DARWIN: abi_str = "darwin"; break;
2088 default: abi_str = "unknown"; break;
2091 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2093 if (rs6000_altivec_abi)
2094 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2097 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2099 if (rs6000_darwin64_abi)
2100 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2102 if (rs6000_float_gprs)
2103 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2105 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2106 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2107 tf[!!rs6000_align_branch_targets]);
2108 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2109 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2110 rs6000_long_double_type_size);
2111 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2112 (int)rs6000_sched_restricted_insns_priority);
2115 /* Initialize the various global tables that are based on register size. */
2117 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2123 /* Precalculate REGNO_REG_CLASS. */
2124 rs6000_regno_regclass[0] = GENERAL_REGS;
2125 for (r = 1; r < 32; ++r)
2126 rs6000_regno_regclass[r] = BASE_REGS;
2128 for (r = 32; r < 64; ++r)
2129 rs6000_regno_regclass[r] = FLOAT_REGS;
2131 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2132 rs6000_regno_regclass[r] = NO_REGS;
2134 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2135 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2137 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2138 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2139 rs6000_regno_regclass[r] = CR_REGS;
2141 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2142 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2143 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2144 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2145 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2146 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2147 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2148 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2149 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2150 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2152 /* Precalculate vector information, this must be set up before the
2153 rs6000_hard_regno_nregs_internal below. */
2154 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2156 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2157 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2158 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2161 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2162 rs6000_constraints[c] = NO_REGS;
2164 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2165 believes it can use native alignment or still uses 128-bit alignment. */
2166 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2177 /* V2DF mode, VSX only. */
2180 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2181 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2182 rs6000_vector_align[V2DFmode] = align64;
2185 /* V4SF mode, either VSX or Altivec. */
2188 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2189 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2190 rs6000_vector_align[V4SFmode] = align32;
2192 else if (TARGET_ALTIVEC)
2194 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2195 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2196 rs6000_vector_align[V4SFmode] = align32;
2199 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2203 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2204 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2205 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2206 rs6000_vector_align[V4SImode] = align32;
2207 rs6000_vector_align[V8HImode] = align32;
2208 rs6000_vector_align[V16QImode] = align32;
2212 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2213 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2214 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2218 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2219 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2220 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2224 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2225 Altivec doesn't have 64-bit support. */
2228 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2229 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2230 rs6000_vector_align[V2DImode] = align64;
2233 /* DFmode, see if we want to use the VSX unit. */
2234 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2236 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2237 rs6000_vector_mem[DFmode]
2238 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2239 rs6000_vector_align[DFmode] = align64;
2242 /* TODO add SPE and paired floating point vector support. */
2244 /* Register class constaints for the constraints that depend on compile
2246 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2247 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2249 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2250 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2254 /* At present, we just use VSX_REGS, but we have different constraints
2255 based on the use, in case we want to fine tune the default register
2256 class used. wa = any VSX register, wf = register class to use for
2257 V4SF, wd = register class to use for V2DF, and ws = register classs to
2258 use for DF scalars. */
2259 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2260 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2261 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2262 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2268 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2270 /* Set up the reload helper functions. */
2271 if (TARGET_VSX || TARGET_ALTIVEC)
2275 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2276 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2277 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2278 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2279 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2280 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2281 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2282 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2283 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2284 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2285 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2286 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2290 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2291 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2292 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2293 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2294 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2295 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2296 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2297 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2298 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2299 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2300 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2301 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2305 /* Precalculate HARD_REGNO_NREGS. */
2306 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2307 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2308 rs6000_hard_regno_nregs[m][r]
2309 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2311 /* Precalculate HARD_REGNO_MODE_OK. */
2312 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2313 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2314 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2315 rs6000_hard_regno_mode_ok_p[m][r] = true;
2317 /* Precalculate CLASS_MAX_NREGS sizes. */
2318 for (c = 0; c < LIM_REG_CLASSES; ++c)
2322 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2323 reg_size = UNITS_PER_VSX_WORD;
2325 else if (c == ALTIVEC_REGS)
2326 reg_size = UNITS_PER_ALTIVEC_WORD;
2328 else if (c == FLOAT_REGS)
2329 reg_size = UNITS_PER_FP_WORD;
2332 reg_size = UNITS_PER_WORD;
2334 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2335 rs6000_class_max_nregs[m][c]
2336 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2339 if (TARGET_E500_DOUBLE)
2340 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2342 /* Calculate which modes to automatically generate code to use a the
2343 reciprocal divide and square root instructions. In the future, possibly
2344 automatically generate the instructions even if the user did not specify
2345 -mrecip. The older machines double precision reciprocal sqrt estimate is
2346 not accurate enough. */
2347 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2349 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2351 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2352 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2353 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2354 if (VECTOR_UNIT_VSX_P (V2DFmode))
2355 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2357 if (TARGET_FRSQRTES)
2358 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2360 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2361 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2362 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2363 if (VECTOR_UNIT_VSX_P (V2DFmode))
2364 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2366 if (rs6000_recip_control)
2368 if (!flag_finite_math_only)
2369 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2370 if (flag_trapping_math)
2371 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2372 if (!flag_reciprocal_math)
2373 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2374 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2376 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2377 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2378 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2380 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2381 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2382 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2384 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2385 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2386 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2388 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2389 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2390 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2392 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2393 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2394 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2396 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2397 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2398 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2400 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2401 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2402 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2404 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2405 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2406 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2410 if (global_init_p || TARGET_DEBUG_TARGET)
2412 if (TARGET_DEBUG_REG)
2413 rs6000_debug_reg_global ();
2415 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2417 "SImode variable mult cost = %d\n"
2418 "SImode constant mult cost = %d\n"
2419 "SImode short constant mult cost = %d\n"
2420 "DImode multipliciation cost = %d\n"
2421 "SImode division cost = %d\n"
2422 "DImode division cost = %d\n"
2423 "Simple fp operation cost = %d\n"
2424 "DFmode multiplication cost = %d\n"
2425 "SFmode division cost = %d\n"
2426 "DFmode division cost = %d\n"
2427 "cache line size = %d\n"
2428 "l1 cache size = %d\n"
2429 "l2 cache size = %d\n"
2430 "simultaneous prefetches = %d\n"
2433 rs6000_cost->mulsi_const,
2434 rs6000_cost->mulsi_const9,
2442 rs6000_cost->cache_line_size,
2443 rs6000_cost->l1_cache_size,
2444 rs6000_cost->l2_cache_size,
2445 rs6000_cost->simultaneous_prefetches);
2450 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2453 darwin_rs6000_override_options (void)
2455 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2457 rs6000_altivec_abi = 1;
2458 TARGET_ALTIVEC_VRSAVE = 1;
2460 if (DEFAULT_ABI == ABI_DARWIN
2462 darwin_one_byte_bool = 1;
2464 if (TARGET_64BIT && ! TARGET_POWERPC64)
2466 target_flags |= MASK_POWERPC64;
2467 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2471 rs6000_default_long_calls = 1;
2472 target_flags |= MASK_SOFT_FLOAT;
2475 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2477 if (!flag_mkernel && !flag_apple_kext
2479 && ! (target_flags_explicit & MASK_ALTIVEC))
2480 target_flags |= MASK_ALTIVEC;
2482 /* Unless the user (not the configurer) has explicitly overridden
2483 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2484 G4 unless targetting the kernel. */
2487 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2488 && ! (target_flags_explicit & MASK_ALTIVEC)
2489 && ! global_options_set.x_rs6000_cpu_index)
2491 target_flags |= MASK_ALTIVEC;
2496 /* If not otherwise specified by a target, make 'long double' equivalent to
2499 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2500 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2503 /* Override command line options. Mostly we process the processor type and
2504 sometimes adjust other TARGET_ options. */
2507 rs6000_option_override_internal (bool global_init_p)
2510 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2514 struct cl_target_option *main_target_opt
2515 = ((global_init_p || target_option_default_node == NULL)
2516 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2518 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2519 library functions, so warn about it. The flag may be useful for
2520 performance studies from time to time though, so don't disable it
2522 if (global_options_set.x_rs6000_alignment_flags
2523 && rs6000_alignment_flags == MASK_ALIGN_POWER
2524 && DEFAULT_ABI == ABI_DARWIN
2526 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2527 " it is incompatible with the installed C and C++ libraries");
2529 if (global_options_set.x_rs6000_spe_abi
2532 error ("not configured for SPE ABI");
2534 /* Numerous experiment shows that IRA based loop pressure
2535 calculation works better for RTL loop invariant motion on targets
2536 with enough (>= 32) registers. It is an expensive optimization.
2537 So it is on only for peak performance. */
2538 if (optimize >= 3 && global_init_p)
2539 flag_ira_loop_pressure = 1;
2541 /* Set the pointer size. */
2544 rs6000_pmode = (int)DImode;
2545 rs6000_pointer_size = 64;
2549 rs6000_pmode = (int)SImode;
2550 rs6000_pointer_size = 32;
2553 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2554 #ifdef OS_MISSING_POWERPC64
2555 if (OS_MISSING_POWERPC64)
2556 set_masks &= ~MASK_POWERPC64;
2558 #ifdef OS_MISSING_ALTIVEC
2559 if (OS_MISSING_ALTIVEC)
2560 set_masks &= ~MASK_ALTIVEC;
2563 /* Don't override by the processor default if given explicitly. */
2564 set_masks &= ~target_flags_explicit;
2566 /* Identify the processor type. */
2569 if (TARGET_POWERPC64)
2570 default_cpu = "powerpc64";
2571 else if (TARGET_POWERPC)
2572 default_cpu = "powerpc";
2575 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2576 the cpu in a target attribute or pragma, but did not specify a tuning
2577 option, use the cpu for the tuning option rather than the option specified
2578 with -mtune on the command line. */
2579 if (rs6000_cpu_index > 0)
2580 cpu_index = rs6000_cpu_index;
2581 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2582 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2584 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2586 if (rs6000_tune_index > 0)
2587 tune_index = rs6000_tune_index;
2589 rs6000_tune_index = tune_index = cpu_index;
2593 target_flags &= ~set_masks;
2594 target_flags |= (processor_target_table[cpu_index].target_enable
2598 rs6000_cpu = ((tune_index >= 0)
2599 ? processor_target_table[tune_index].processor
2601 ? PROCESSOR_DEFAULT64
2602 : PROCESSOR_DEFAULT));
2604 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2605 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2608 error ("AltiVec not supported in this target");
2610 error ("SPE not supported in this target");
2613 /* Disable Cell microcode if we are optimizing for the Cell
2614 and not optimizing for size. */
2615 if (rs6000_gen_cell_microcode == -1)
2616 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2619 /* If we are optimizing big endian systems for space and it's OK to
2620 use instructions that would be microcoded on the Cell, use the
2621 load/store multiple and string instructions. */
2622 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2623 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2625 /* Don't allow -mmultiple or -mstring on little endian systems
2626 unless the cpu is a 750, because the hardware doesn't support the
2627 instructions used in little endian mode, and causes an alignment
2628 trap. The 750 does not cause an alignment trap (except when the
2629 target is unaligned). */
2631 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2633 if (TARGET_MULTIPLE)
2635 target_flags &= ~MASK_MULTIPLE;
2636 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2637 warning (0, "-mmultiple is not supported on little endian systems");
2642 target_flags &= ~MASK_STRING;
2643 if ((target_flags_explicit & MASK_STRING) != 0)
2644 warning (0, "-mstring is not supported on little endian systems");
2648 /* Add some warnings for VSX. */
2651 const char *msg = NULL;
2652 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2653 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2655 if (target_flags_explicit & MASK_VSX)
2656 msg = N_("-mvsx requires hardware floating point");
2658 target_flags &= ~ MASK_VSX;
2660 else if (TARGET_PAIRED_FLOAT)
2661 msg = N_("-mvsx and -mpaired are incompatible");
2662 /* The hardware will allow VSX and little endian, but until we make sure
2663 things like vector select, etc. work don't allow VSX on little endian
2664 systems at this point. */
2665 else if (!BYTES_BIG_ENDIAN)
2666 msg = N_("-mvsx used with little endian code");
2667 else if (TARGET_AVOID_XFORM > 0)
2668 msg = N_("-mvsx needs indexed addressing");
2669 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2671 if (target_flags_explicit & MASK_VSX)
2672 msg = N_("-mvsx and -mno-altivec are incompatible");
2674 msg = N_("-mno-altivec disables vsx");
2680 target_flags &= ~ MASK_VSX;
2681 target_flags_explicit |= MASK_VSX;
2685 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2686 unless the user explicitly used the -mno-<option> to disable the code. */
2688 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2689 else if (TARGET_POPCNTD)
2690 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2691 else if (TARGET_DFP)
2692 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2693 else if (TARGET_CMPB)
2694 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2695 else if (TARGET_FPRND)
2696 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2697 else if (TARGET_POPCNTB)
2698 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2699 else if (TARGET_ALTIVEC)
2700 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2702 /* E500mc does "better" if we inline more aggressively. Respect the
2703 user's opinion, though. */
2704 if (rs6000_block_move_inline_limit == 0
2705 && (rs6000_cpu == PROCESSOR_PPCE500MC
2706 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2707 rs6000_block_move_inline_limit = 128;
2709 /* store_one_arg depends on expand_block_move to handle at least the
2710 size of reg_parm_stack_space. */
2711 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2712 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2716 /* If the appropriate debug option is enabled, replace the target hooks
2717 with debug versions that call the real version and then prints
2718 debugging information. */
2719 if (TARGET_DEBUG_COST)
2721 targetm.rtx_costs = rs6000_debug_rtx_costs;
2722 targetm.address_cost = rs6000_debug_address_cost;
2723 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2726 if (TARGET_DEBUG_ADDR)
2728 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2729 targetm.legitimize_address = rs6000_debug_legitimize_address;
2730 rs6000_secondary_reload_class_ptr
2731 = rs6000_debug_secondary_reload_class;
2732 rs6000_secondary_memory_needed_ptr
2733 = rs6000_debug_secondary_memory_needed;
2734 rs6000_cannot_change_mode_class_ptr
2735 = rs6000_debug_cannot_change_mode_class;
2736 rs6000_preferred_reload_class_ptr
2737 = rs6000_debug_preferred_reload_class;
2738 rs6000_legitimize_reload_address_ptr
2739 = rs6000_debug_legitimize_reload_address;
2740 rs6000_mode_dependent_address_ptr
2741 = rs6000_debug_mode_dependent_address;
2744 if (rs6000_veclibabi_name)
2746 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2747 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2750 error ("unknown vectorization library ABI type (%s) for "
2751 "-mveclibabi= switch", rs6000_veclibabi_name);
2757 if (!global_options_set.x_rs6000_long_double_type_size)
2759 if (main_target_opt != NULL
2760 && (main_target_opt->x_rs6000_long_double_type_size
2761 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2762 error ("target attribute or pragma changes long double size");
2764 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2767 #ifndef POWERPC_LINUX
2768 if (!global_options_set.x_rs6000_ieeequad)
2769 rs6000_ieeequad = 1;
2772 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2773 target attribute or pragma which automatically enables both options,
2774 unless the altivec ABI was set. This is set by default for 64-bit, but
2776 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2777 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2779 /* Enable Altivec ABI for AIX -maltivec. */
2780 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2782 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2783 error ("target attribute or pragma changes AltiVec ABI");
2785 rs6000_altivec_abi = 1;
2788 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2789 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2790 be explicitly overridden in either case. */
2793 if (!global_options_set.x_rs6000_altivec_abi
2794 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2796 if (main_target_opt != NULL &&
2797 !main_target_opt->x_rs6000_altivec_abi)
2798 error ("target attribute or pragma changes AltiVec ABI");
2800 rs6000_altivec_abi = 1;
2803 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2804 if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
2805 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2808 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2809 So far, the only darwin64 targets are also MACH-O. */
2811 && DEFAULT_ABI == ABI_DARWIN
2814 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2815 error ("target attribute or pragma changes darwin64 ABI");
2818 rs6000_darwin64_abi = 1;
2819 /* Default to natural alignment, for better performance. */
2820 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2824 /* Place FP constants in the constant pool instead of TOC
2825 if section anchors enabled. */
2826 if (flag_section_anchors)
2827 TARGET_NO_FP_IN_TOC = 1;
2829 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2830 SUBTARGET_OVERRIDE_OPTIONS;
2832 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2833 SUBSUBTARGET_OVERRIDE_OPTIONS;
2835 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2836 SUB3TARGET_OVERRIDE_OPTIONS;
2839 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2840 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2842 /* The e500 and e500mc do not have string instructions, and we set
2843 MASK_STRING above when optimizing for size. */
2844 if ((target_flags & MASK_STRING) != 0)
2845 target_flags = target_flags & ~MASK_STRING;
2847 else if (global_options_set.x_rs6000_cpu_index)
2849 /* For the powerpc-eabispe configuration, we set all these by
2850 default, so let's unset them if we manually set another
2851 CPU that is not the E500. */
2852 if (main_target_opt != NULL
2853 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2854 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2855 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2856 error ("target attribute or pragma changes SPE ABI");
2859 if (!global_options_set.x_rs6000_spe_abi)
2861 if (!global_options_set.x_rs6000_spe)
2863 if (!global_options_set.x_rs6000_float_gprs)
2864 rs6000_float_gprs = 0;
2866 if (!(target_flags_explicit & MASK_ISEL))
2867 target_flags &= ~MASK_ISEL;
2870 /* Detect invalid option combinations with E500. */
2873 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2874 && rs6000_cpu != PROCESSOR_POWER5
2875 && rs6000_cpu != PROCESSOR_POWER6
2876 && rs6000_cpu != PROCESSOR_POWER7
2877 && rs6000_cpu != PROCESSOR_PPCA2
2878 && rs6000_cpu != PROCESSOR_CELL);
2879 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2880 || rs6000_cpu == PROCESSOR_POWER5
2881 || rs6000_cpu == PROCESSOR_POWER7);
2882 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2883 || rs6000_cpu == PROCESSOR_POWER5
2884 || rs6000_cpu == PROCESSOR_POWER6
2885 || rs6000_cpu == PROCESSOR_POWER7
2886 || rs6000_cpu == PROCESSOR_PPCE500MC
2887 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2889 /* Allow debug switches to override the above settings. These are set to -1
2890 in rs6000.opt to indicate the user hasn't directly set the switch. */
2891 if (TARGET_ALWAYS_HINT >= 0)
2892 rs6000_always_hint = TARGET_ALWAYS_HINT;
2894 if (TARGET_SCHED_GROUPS >= 0)
2895 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2897 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
2898 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2900 rs6000_sched_restricted_insns_priority
2901 = (rs6000_sched_groups ? 1 : 0);
2903 /* Handle -msched-costly-dep option. */
2904 rs6000_sched_costly_dep
2905 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2907 if (rs6000_sched_costly_dep_str)
2909 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2910 rs6000_sched_costly_dep = no_dep_costly;
2911 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2912 rs6000_sched_costly_dep = all_deps_costly;
2913 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2914 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2915 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2916 rs6000_sched_costly_dep = store_to_load_dep_costly;
2918 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2919 atoi (rs6000_sched_costly_dep_str));
2922 /* Handle -minsert-sched-nops option. */
2923 rs6000_sched_insert_nops
2924 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2926 if (rs6000_sched_insert_nops_str)
2928 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2929 rs6000_sched_insert_nops = sched_finish_none;
2930 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2931 rs6000_sched_insert_nops = sched_finish_pad_groups;
2932 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2933 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2935 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2936 atoi (rs6000_sched_insert_nops_str));
2941 #ifdef TARGET_REGNAMES
2942 /* If the user desires alternate register names, copy in the
2943 alternate names now. */
2944 if (TARGET_REGNAMES)
2945 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2948 /* Set aix_struct_return last, after the ABI is determined.
2949 If -maix-struct-return or -msvr4-struct-return was explicitly
2950 used, don't override with the ABI default. */
2951 if (!global_options_set.x_aix_struct_return)
2952 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2955 /* IBM XL compiler defaults to unsigned bitfields. */
2956 if (TARGET_XL_COMPAT)
2957 flag_signed_bitfields = 0;
2960 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2961 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2964 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2966 /* We can only guarantee the availability of DI pseudo-ops when
2967 assembling for 64-bit targets. */
2970 targetm.asm_out.aligned_op.di = NULL;
2971 targetm.asm_out.unaligned_op.di = NULL;
2975 /* Set branch target alignment, if not optimizing for size. */
2978 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2979 aligned 8byte to avoid misprediction by the branch predictor. */
2980 if (rs6000_cpu == PROCESSOR_TITAN
2981 || rs6000_cpu == PROCESSOR_CELL)
2983 if (align_functions <= 0)
2984 align_functions = 8;
2985 if (align_jumps <= 0)
2987 if (align_loops <= 0)
2990 if (rs6000_align_branch_targets)
2992 if (align_functions <= 0)
2993 align_functions = 16;
2994 if (align_jumps <= 0)
2996 if (align_loops <= 0)
2998 can_override_loop_align = 1;
3002 if (align_jumps_max_skip <= 0)
3003 align_jumps_max_skip = 15;
3004 if (align_loops_max_skip <= 0)
3005 align_loops_max_skip = 15;
3008 /* Arrange to save and restore machine status around nested functions. */
3009 init_machine_status = rs6000_init_machine_status;
3011 /* We should always be splitting complex arguments, but we can't break
3012 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3013 if (DEFAULT_ABI != ABI_AIX)
3014 targetm.calls.split_complex_arg = NULL;
3017 /* Initialize rs6000_cost with the appropriate target costs. */
3019 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3023 case PROCESSOR_RIOS1:
3024 rs6000_cost = &rios1_cost;
3027 case PROCESSOR_RIOS2:
3028 rs6000_cost = &rios2_cost;
3031 case PROCESSOR_RS64A:
3032 rs6000_cost = &rs64a_cost;
3035 case PROCESSOR_MPCCORE:
3036 rs6000_cost = &mpccore_cost;
3039 case PROCESSOR_PPC403:
3040 rs6000_cost = &ppc403_cost;
3043 case PROCESSOR_PPC405:
3044 rs6000_cost = &ppc405_cost;
3047 case PROCESSOR_PPC440:
3048 rs6000_cost = &ppc440_cost;
3051 case PROCESSOR_PPC476:
3052 rs6000_cost = &ppc476_cost;
3055 case PROCESSOR_PPC601:
3056 rs6000_cost = &ppc601_cost;
3059 case PROCESSOR_PPC603:
3060 rs6000_cost = &ppc603_cost;
3063 case PROCESSOR_PPC604:
3064 rs6000_cost = &ppc604_cost;
3067 case PROCESSOR_PPC604e:
3068 rs6000_cost = &ppc604e_cost;
3071 case PROCESSOR_PPC620:
3072 rs6000_cost = &ppc620_cost;
3075 case PROCESSOR_PPC630:
3076 rs6000_cost = &ppc630_cost;
3079 case PROCESSOR_CELL:
3080 rs6000_cost = &ppccell_cost;
3083 case PROCESSOR_PPC750:
3084 case PROCESSOR_PPC7400:
3085 rs6000_cost = &ppc750_cost;
3088 case PROCESSOR_PPC7450:
3089 rs6000_cost = &ppc7450_cost;
3092 case PROCESSOR_PPC8540:
3093 rs6000_cost = &ppc8540_cost;
3096 case PROCESSOR_PPCE300C2:
3097 case PROCESSOR_PPCE300C3:
3098 rs6000_cost = &ppce300c2c3_cost;
3101 case PROCESSOR_PPCE500MC:
3102 rs6000_cost = &ppce500mc_cost;
3105 case PROCESSOR_PPCE500MC64:
3106 rs6000_cost = &ppce500mc64_cost;
3109 case PROCESSOR_TITAN:
3110 rs6000_cost = &titan_cost;
3113 case PROCESSOR_POWER4:
3114 case PROCESSOR_POWER5:
3115 rs6000_cost = &power4_cost;
3118 case PROCESSOR_POWER6:
3119 rs6000_cost = &power6_cost;
3122 case PROCESSOR_POWER7:
3123 rs6000_cost = &power7_cost;
3126 case PROCESSOR_PPCA2:
3127 rs6000_cost = &ppca2_cost;
3136 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3137 rs6000_cost->simultaneous_prefetches,
3138 global_options.x_param_values,
3139 global_options_set.x_param_values);
3140 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3141 global_options.x_param_values,
3142 global_options_set.x_param_values);
3143 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3144 rs6000_cost->cache_line_size,
3145 global_options.x_param_values,
3146 global_options_set.x_param_values);
3147 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3148 global_options.x_param_values,
3149 global_options_set.x_param_values);
3151 /* If using typedef char *va_list, signal that
3152 __builtin_va_start (&ap, 0) can be optimized to
3153 ap = __builtin_next_arg (0). */
3154 if (DEFAULT_ABI != ABI_V4)
3155 targetm.expand_builtin_va_start = NULL;
3158 /* Set up single/double float flags.
3159 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3160 then set both flags. */
3161 if (TARGET_HARD_FLOAT && TARGET_FPRS
3162 && rs6000_single_float == 0 && rs6000_double_float == 0)
3163 rs6000_single_float = rs6000_double_float = 1;
3165 /* Reset single and double FP flags if target is E500. */
3168 rs6000_single_float = rs6000_double_float = 0;
3169 if (TARGET_E500_SINGLE)
3170 rs6000_single_float = 1;
3171 if (TARGET_E500_DOUBLE)
3172 rs6000_single_float = rs6000_double_float = 1;
3175 if (main_target_opt)
3177 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3178 error ("target attribute or pragma changes single precision floating "
3180 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3181 error ("target attribute or pragma changes double precision floating "
3185 /* If not explicitly specified via option, decide whether to generate indexed
3186 load/store instructions. */
3187 if (TARGET_AVOID_XFORM == -1)
3188 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3189 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3190 need indexed accesses and the type used is the scalar type of the element
3191 being loaded or stored. */
3192 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3193 && !TARGET_ALTIVEC);
3195 /* Set the -mrecip options. */
3196 if (rs6000_recip_name)
3198 char *p = ASTRDUP (rs6000_recip_name);
3200 unsigned int mask, i;
3203 while ((q = strtok (p, ",")) != NULL)
3214 if (!strcmp (q, "default"))
3215 mask = ((TARGET_RECIP_PRECISION)
3216 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3219 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3220 if (!strcmp (q, recip_options[i].string))
3222 mask = recip_options[i].mask;
3226 if (i == ARRAY_SIZE (recip_options))
3228 error ("unknown option for -mrecip=%s", q);
3236 rs6000_recip_control &= ~mask;
3238 rs6000_recip_control |= mask;
3242 rs6000_init_hard_regno_mode_ok (global_init_p);
3244 /* Save the initial options in case the user does function specific options */
3246 target_option_default_node = target_option_current_node
3247 = build_target_option_node ();
3252 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3253 define the target cpu type. */
3256 rs6000_option_override (void)
3258 (void) rs6000_option_override_internal (true);
3262 /* Implement targetm.vectorize.builtin_mask_for_load. */
3264 rs6000_builtin_mask_for_load (void)
3266 if (TARGET_ALTIVEC || TARGET_VSX)
3267 return altivec_builtin_mask_for_load;
3272 /* Implement LOOP_ALIGN. */
3274 rs6000_loop_align (rtx label)
3279 /* Don't override loop alignment if -falign-loops was specified. */
3280 if (!can_override_loop_align)
3281 return align_loops_log;
3283 bb = BLOCK_FOR_INSN (label);
3284 ninsns = num_loop_insns(bb->loop_father);
3286 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3287 if (ninsns > 4 && ninsns <= 8
3288 && (rs6000_cpu == PROCESSOR_POWER4
3289 || rs6000_cpu == PROCESSOR_POWER5
3290 || rs6000_cpu == PROCESSOR_POWER6
3291 || rs6000_cpu == PROCESSOR_POWER7))
3294 return align_loops_log;
3297 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3299 rs6000_loop_align_max_skip (rtx label)
3301 return (1 << rs6000_loop_align (label)) - 1;
3304 /* Implement targetm.vectorize.builtin_conversion.
3305 Returns a decl of a function that implements conversion of an integer vector
3306 into a floating-point vector, or vice-versa. DEST_TYPE is the
3307 destination type and SRC_TYPE the source type of the conversion.
3308 Return NULL_TREE if it is not available. */
3310 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3312 enum tree_code code = (enum tree_code) tcode;
3316 case FIX_TRUNC_EXPR:
3317 switch (TYPE_MODE (dest_type))
3320 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3323 return TYPE_UNSIGNED (dest_type)
3324 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3325 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3328 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3331 return TYPE_UNSIGNED (dest_type)
3332 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3333 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3340 switch (TYPE_MODE (src_type))
3343 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3346 return TYPE_UNSIGNED (src_type)
3347 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3348 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3351 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3354 return TYPE_UNSIGNED (src_type)
3355 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3356 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3367 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3369 rs6000_builtin_mul_widen_even (tree type)
3371 if (!TARGET_ALTIVEC)
3374 switch (TYPE_MODE (type))
3377 return TYPE_UNSIGNED (type)
3378 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3379 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3382 return TYPE_UNSIGNED (type)
3383 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3384 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3390 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3392 rs6000_builtin_mul_widen_odd (tree type)
3394 if (!TARGET_ALTIVEC)
3397 switch (TYPE_MODE (type))
3400 return TYPE_UNSIGNED (type)
3401 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3402 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3405 return TYPE_UNSIGNED (type)
3406 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3407 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3414 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3415 after applying N number of iterations. This routine does not determine
3416 how may iterations are required to reach desired alignment. */
3419 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3426 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3429 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3439 /* Assuming that all other types are naturally aligned. CHECKME! */
3444 /* Return true if the vector misalignment factor is supported by the
3447 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3454 /* Return if movmisalign pattern is not supported for this mode. */
3455 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3458 if (misalignment == -1)
3460 /* Misalignment factor is unknown at compile time but we know
3461 it's word aligned. */
3462 if (rs6000_vector_alignment_reachable (type, is_packed))
3464 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3466 if (element_size == 64 || element_size == 32)
3473 /* VSX supports word-aligned vector. */
3474 if (misalignment % 4 == 0)
3480 /* Implement targetm.vectorize.builtin_vec_perm. */
3482 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3484 tree inner_type = TREE_TYPE (type);
3485 bool uns_p = TYPE_UNSIGNED (inner_type);
3488 *mask_element_type = unsigned_char_type_node;
3490 switch (TYPE_MODE (type))
3494 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3495 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3500 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3501 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3506 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3507 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3511 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3515 if (!TARGET_ALLOW_DF_PERMUTE)
3518 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3522 if (!TARGET_ALLOW_DF_PERMUTE)
3526 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3527 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3539 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3541 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3542 tree vectype, int misalign)
3546 switch (type_of_cost)
3556 case cond_branch_not_taken:
3560 case cond_branch_taken:
3563 case unaligned_load:
3564 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3566 elements = TYPE_VECTOR_SUBPARTS (vectype);
3568 /* Double word aligned. */
3576 /* Double word aligned. */
3580 /* Unknown misalignment. */
3593 /* Misaligned loads are not supported. */
3598 case unaligned_store:
3599 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3601 elements = TYPE_VECTOR_SUBPARTS (vectype);
3603 /* Double word aligned. */
3611 /* Double word aligned. */
3615 /* Unknown misalignment. */
3628 /* Misaligned stores are not supported. */
3638 /* Implement targetm.vectorize.preferred_simd_mode. */
3640 static enum machine_mode
3641 rs6000_preferred_simd_mode (enum machine_mode mode)
3650 if (TARGET_ALTIVEC || TARGET_VSX)
3674 if (TARGET_PAIRED_FLOAT
3680 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3681 library with vectorized intrinsics. */
3684 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3687 const char *suffix = NULL;
3688 tree fntype, new_fndecl, bdecl = NULL_TREE;
3691 enum machine_mode el_mode, in_mode;
3694 /* Libmass is suitable for unsafe math only as it does not correctly support
3695 parts of IEEE with the required precision such as denormals. Only support
3696 it if we have VSX to use the simd d2 or f4 functions.
3697 XXX: Add variable length support. */
3698 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3701 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3702 n = TYPE_VECTOR_SUBPARTS (type_out);
3703 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3704 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3705 if (el_mode != in_mode
3709 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3711 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3714 case BUILT_IN_ATAN2:
3715 case BUILT_IN_HYPOT:
3721 case BUILT_IN_ACOSH:
3723 case BUILT_IN_ASINH:
3725 case BUILT_IN_ATANH:
3733 case BUILT_IN_EXPM1:
3734 case BUILT_IN_LGAMMA:
3735 case BUILT_IN_LOG10:
3736 case BUILT_IN_LOG1P:
3744 bdecl = implicit_built_in_decls[fn];
3745 suffix = "d2"; /* pow -> powd2 */
3746 if (el_mode != DFmode
3751 case BUILT_IN_ATAN2F:
3752 case BUILT_IN_HYPOTF:
3757 case BUILT_IN_ACOSF:
3758 case BUILT_IN_ACOSHF:
3759 case BUILT_IN_ASINF:
3760 case BUILT_IN_ASINHF:
3761 case BUILT_IN_ATANF:
3762 case BUILT_IN_ATANHF:
3763 case BUILT_IN_CBRTF:
3765 case BUILT_IN_COSHF:
3767 case BUILT_IN_ERFCF:
3768 case BUILT_IN_EXP2F:
3770 case BUILT_IN_EXPM1F:
3771 case BUILT_IN_LGAMMAF:
3772 case BUILT_IN_LOG10F:
3773 case BUILT_IN_LOG1PF:
3774 case BUILT_IN_LOG2F:
3777 case BUILT_IN_SINHF:
3778 case BUILT_IN_SQRTF:
3780 case BUILT_IN_TANHF:
3781 bdecl = implicit_built_in_decls[fn];
3782 suffix = "4"; /* powf -> powf4 */
3783 if (el_mode != SFmode
3795 gcc_assert (suffix != NULL);
3796 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3797 strcpy (name, bname + sizeof ("__builtin_") - 1);
3798 strcat (name, suffix);
3801 fntype = build_function_type_list (type_out, type_in, NULL);
3802 else if (n_args == 2)
3803 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3807 /* Build a function declaration for the vectorized function. */
3808 new_fndecl = build_decl (BUILTINS_LOCATION,
3809 FUNCTION_DECL, get_identifier (name), fntype);
3810 TREE_PUBLIC (new_fndecl) = 1;
3811 DECL_EXTERNAL (new_fndecl) = 1;
3812 DECL_IS_NOVOPS (new_fndecl) = 1;
3813 TREE_READONLY (new_fndecl) = 1;
3818 /* Returns a function decl for a vectorized version of the builtin function
3819 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3820 if it is not available. */
3823 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3826 enum machine_mode in_mode, out_mode;
3829 if (TREE_CODE (type_out) != VECTOR_TYPE
3830 || TREE_CODE (type_in) != VECTOR_TYPE
3831 || !TARGET_VECTORIZE_BUILTINS)
3834 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3835 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3836 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3837 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3839 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3841 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3844 case BUILT_IN_COPYSIGN:
3845 if (VECTOR_UNIT_VSX_P (V2DFmode)
3846 && out_mode == DFmode && out_n == 2
3847 && in_mode == DFmode && in_n == 2)
3848 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3850 case BUILT_IN_COPYSIGNF:
3851 if (out_mode != SFmode || out_n != 4
3852 || in_mode != SFmode || in_n != 4)
3854 if (VECTOR_UNIT_VSX_P (V4SFmode))
3855 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3856 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3857 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3860 if (VECTOR_UNIT_VSX_P (V2DFmode)
3861 && out_mode == DFmode && out_n == 2
3862 && in_mode == DFmode && in_n == 2)
3863 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3865 case BUILT_IN_SQRTF:
3866 if (VECTOR_UNIT_VSX_P (V4SFmode)
3867 && out_mode == SFmode && out_n == 4
3868 && in_mode == SFmode && in_n == 4)
3869 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3872 if (VECTOR_UNIT_VSX_P (V2DFmode)
3873 && out_mode == DFmode && out_n == 2
3874 && in_mode == DFmode && in_n == 2)
3875 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3877 case BUILT_IN_CEILF:
3878 if (out_mode != SFmode || out_n != 4
3879 || in_mode != SFmode || in_n != 4)
3881 if (VECTOR_UNIT_VSX_P (V4SFmode))
3882 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3883 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3884 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3886 case BUILT_IN_FLOOR:
3887 if (VECTOR_UNIT_VSX_P (V2DFmode)
3888 && out_mode == DFmode && out_n == 2
3889 && in_mode == DFmode && in_n == 2)
3890 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3892 case BUILT_IN_FLOORF:
3893 if (out_mode != SFmode || out_n != 4
3894 || in_mode != SFmode || in_n != 4)
3896 if (VECTOR_UNIT_VSX_P (V4SFmode))
3897 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3898 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3899 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3902 if (VECTOR_UNIT_VSX_P (V2DFmode)
3903 && out_mode == DFmode && out_n == 2
3904 && in_mode == DFmode && in_n == 2)
3905 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3908 if (VECTOR_UNIT_VSX_P (V4SFmode)
3909 && out_mode == SFmode && out_n == 4
3910 && in_mode == SFmode && in_n == 4)
3911 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3912 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3913 && out_mode == SFmode && out_n == 4
3914 && in_mode == SFmode && in_n == 4)
3915 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3917 case BUILT_IN_TRUNC:
3918 if (VECTOR_UNIT_VSX_P (V2DFmode)
3919 && out_mode == DFmode && out_n == 2
3920 && in_mode == DFmode && in_n == 2)
3921 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3923 case BUILT_IN_TRUNCF:
3924 if (out_mode != SFmode || out_n != 4
3925 || in_mode != SFmode || in_n != 4)
3927 if (VECTOR_UNIT_VSX_P (V4SFmode))
3928 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3929 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3930 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3932 case BUILT_IN_NEARBYINT:
3933 if (VECTOR_UNIT_VSX_P (V2DFmode)
3934 && flag_unsafe_math_optimizations
3935 && out_mode == DFmode && out_n == 2
3936 && in_mode == DFmode && in_n == 2)
3937 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3939 case BUILT_IN_NEARBYINTF:
3940 if (VECTOR_UNIT_VSX_P (V4SFmode)
3941 && flag_unsafe_math_optimizations
3942 && out_mode == SFmode && out_n == 4
3943 && in_mode == SFmode && in_n == 4)
3944 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3947 if (VECTOR_UNIT_VSX_P (V2DFmode)
3948 && !flag_trapping_math
3949 && out_mode == DFmode && out_n == 2
3950 && in_mode == DFmode && in_n == 2)
3951 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3953 case BUILT_IN_RINTF:
3954 if (VECTOR_UNIT_VSX_P (V4SFmode)
3955 && !flag_trapping_math
3956 && out_mode == SFmode && out_n == 4
3957 && in_mode == SFmode && in_n == 4)
3958 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3965 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3967 enum rs6000_builtins fn
3968 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3971 case RS6000_BUILTIN_RSQRTF:
3972 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3973 && out_mode == SFmode && out_n == 4
3974 && in_mode == SFmode && in_n == 4)
3975 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3977 case RS6000_BUILTIN_RSQRT:
3978 if (VECTOR_UNIT_VSX_P (V2DFmode)
3979 && out_mode == DFmode && out_n == 2
3980 && in_mode == DFmode && in_n == 2)
3981 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3983 case RS6000_BUILTIN_RECIPF:
3984 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3985 && out_mode == SFmode && out_n == 4
3986 && in_mode == SFmode && in_n == 4)
3987 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3989 case RS6000_BUILTIN_RECIP:
3990 if (VECTOR_UNIT_VSX_P (V2DFmode)
3991 && out_mode == DFmode && out_n == 2
3992 && in_mode == DFmode && in_n == 2)
3993 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4000 /* Generate calls to libmass if appropriate. */
4001 if (rs6000_veclib_handler)
4002 return rs6000_veclib_handler (fndecl, type_out, type_in);
4007 /* Default CPU string for rs6000*_file_start functions. */
4008 static const char *rs6000_default_cpu;
4010 /* Do anything needed at the start of the asm file. */
4013 rs6000_file_start (void)
4016 const char *start = buffer;
4017 FILE *file = asm_out_file;
4019 rs6000_default_cpu = TARGET_CPU_DEFAULT;
4021 default_file_start ();
4023 #ifdef TARGET_BI_ARCH
4024 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4025 rs6000_default_cpu = 0;
4028 if (flag_verbose_asm)
4030 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4032 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
4034 fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu);
4038 if (global_options_set.x_rs6000_cpu_index)
4040 fprintf (file, "%s -mcpu=%s", start,
4041 processor_target_table[rs6000_cpu_index].name);
4045 if (global_options_set.x_rs6000_tune_index)
4047 fprintf (file, "%s -mtune=%s", start,
4048 processor_target_table[rs6000_tune_index].name);
4052 if (PPC405_ERRATUM77)
4054 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4058 #ifdef USING_ELFOS_H
4059 switch (rs6000_sdata)
4061 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4062 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4063 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4064 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4067 if (rs6000_sdata && g_switch_value)
4069 fprintf (file, "%s -G %d", start,
4079 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4081 switch_to_section (toc_section);
4082 switch_to_section (text_section);
4087 /* Return nonzero if this function is known to have a null epilogue. */
4090 direct_return (void)
4092 if (reload_completed)
4094 rs6000_stack_t *info = rs6000_stack_info ();
4096 if (info->first_gp_reg_save == 32
4097 && info->first_fp_reg_save == 64
4098 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4099 && ! info->lr_save_p
4100 && ! info->cr_save_p
4101 && info->vrsave_mask == 0
4109 /* Return the number of instructions it takes to form a constant in an
4110 integer register. */
4113 num_insns_constant_wide (HOST_WIDE_INT value)
4115 /* signed constant loadable with {cal|addi} */
4116 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4119 /* constant loadable with {cau|addis} */
4120 else if ((value & 0xffff) == 0
4121 && (value >> 31 == -1 || value >> 31 == 0))
4124 #if HOST_BITS_PER_WIDE_INT == 64
4125 else if (TARGET_POWERPC64)
4127 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4128 HOST_WIDE_INT high = value >> 31;
4130 if (high == 0 || high == -1)
4136 return num_insns_constant_wide (high) + 1;
4138 return num_insns_constant_wide (low) + 1;
4140 return (num_insns_constant_wide (high)
4141 + num_insns_constant_wide (low) + 1);
4150 num_insns_constant (rtx op, enum machine_mode mode)
4152 HOST_WIDE_INT low, high;
4154 switch (GET_CODE (op))
4157 #if HOST_BITS_PER_WIDE_INT == 64
4158 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4159 && mask64_operand (op, mode))
4163 return num_insns_constant_wide (INTVAL (op));
4166 if (mode == SFmode || mode == SDmode)
4171 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4172 if (DECIMAL_FLOAT_MODE_P (mode))
4173 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4175 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4176 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4179 if (mode == VOIDmode || mode == DImode)
4181 high = CONST_DOUBLE_HIGH (op);
4182 low = CONST_DOUBLE_LOW (op);
4189 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4190 if (DECIMAL_FLOAT_MODE_P (mode))
4191 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4193 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4194 high = l[WORDS_BIG_ENDIAN == 0];
4195 low = l[WORDS_BIG_ENDIAN != 0];
4199 return (num_insns_constant_wide (low)
4200 + num_insns_constant_wide (high));
4203 if ((high == 0 && low >= 0)
4204 || (high == -1 && low < 0))
4205 return num_insns_constant_wide (low);
4207 else if (mask64_operand (op, mode))
4211 return num_insns_constant_wide (high) + 1;
4214 return (num_insns_constant_wide (high)
4215 + num_insns_constant_wide (low) + 1);
4223 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4224 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4225 corresponding element of the vector, but for V4SFmode and V2SFmode,
4226 the corresponding "float" is interpreted as an SImode integer. */
4229 const_vector_elt_as_int (rtx op, unsigned int elt)
4233 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4234 gcc_assert (GET_MODE (op) != V2DImode
4235 && GET_MODE (op) != V2DFmode);
4237 tmp = CONST_VECTOR_ELT (op, elt);
4238 if (GET_MODE (op) == V4SFmode
4239 || GET_MODE (op) == V2SFmode)
4240 tmp = gen_lowpart (SImode, tmp);
4241 return INTVAL (tmp);
4244 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4245 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4246 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4247 all items are set to the same value and contain COPIES replicas of the
4248 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4249 operand and the others are set to the value of the operand's msb. */
4252 vspltis_constant (rtx op, unsigned step, unsigned copies)
4254 enum machine_mode mode = GET_MODE (op);
4255 enum machine_mode inner = GET_MODE_INNER (mode);
4263 HOST_WIDE_INT splat_val;
4264 HOST_WIDE_INT msb_val;
4266 if (mode == V2DImode || mode == V2DFmode)
4269 nunits = GET_MODE_NUNITS (mode);
4270 bitsize = GET_MODE_BITSIZE (inner);
4271 mask = GET_MODE_MASK (inner);
4273 val = const_vector_elt_as_int (op, nunits - 1);
4275 msb_val = val > 0 ? 0 : -1;
4277 /* Construct the value to be splatted, if possible. If not, return 0. */
4278 for (i = 2; i <= copies; i *= 2)
4280 HOST_WIDE_INT small_val;
4282 small_val = splat_val >> bitsize;
4284 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4286 splat_val = small_val;
4289 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4290 if (EASY_VECTOR_15 (splat_val))
4293 /* Also check if we can splat, and then add the result to itself. Do so if
4294 the value is positive, of if the splat instruction is using OP's mode;
4295 for splat_val < 0, the splat and the add should use the same mode. */
4296 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4297 && (splat_val >= 0 || (step == 1 && copies == 1)))
4300 /* Also check if are loading up the most significant bit which can be done by
4301 loading up -1 and shifting the value left by -1. */
4302 else if (EASY_VECTOR_MSB (splat_val, inner))
4308 /* Check if VAL is present in every STEP-th element, and the
4309 other elements are filled with its most significant bit. */
4310 for (i = 0; i < nunits - 1; ++i)
4312 HOST_WIDE_INT desired_val;
4313 if (((i + 1) & (step - 1)) == 0)
4316 desired_val = msb_val;
4318 if (desired_val != const_vector_elt_as_int (op, i))
4326 /* Return true if OP is of the given MODE and can be synthesized
4327 with a vspltisb, vspltish or vspltisw. */
4330 easy_altivec_constant (rtx op, enum machine_mode mode)
4332 unsigned step, copies;
4334 if (mode == VOIDmode)
4335 mode = GET_MODE (op);
4336 else if (mode != GET_MODE (op))
4339 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4341 if (mode == V2DFmode)
4342 return zero_constant (op, mode);
4344 if (mode == V2DImode)
4346 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4348 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4349 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4352 if (zero_constant (op, mode))
4355 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4356 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4362 /* Start with a vspltisw. */
4363 step = GET_MODE_NUNITS (mode) / 4;
4366 if (vspltis_constant (op, step, copies))
4369 /* Then try with a vspltish. */
4375 if (vspltis_constant (op, step, copies))
4378 /* And finally a vspltisb. */
4384 if (vspltis_constant (op, step, copies))
4390 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4391 result is OP. Abort if it is not possible. */
4394 gen_easy_altivec_constant (rtx op)
4396 enum machine_mode mode = GET_MODE (op);
4397 int nunits = GET_MODE_NUNITS (mode);
4398 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4399 unsigned step = nunits / 4;
4400 unsigned copies = 1;
4402 /* Start with a vspltisw. */
4403 if (vspltis_constant (op, step, copies))
4404 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4406 /* Then try with a vspltish. */
4412 if (vspltis_constant (op, step, copies))
4413 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4415 /* And finally a vspltisb. */
4421 if (vspltis_constant (op, step, copies))
4422 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4428 output_vec_const_move (rtx *operands)
4431 enum machine_mode mode;
4436 mode = GET_MODE (dest);
4440 if (zero_constant (vec, mode))
4441 return "xxlxor %x0,%x0,%x0";
4443 if (mode == V2DImode
4444 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
4445 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
4446 return "vspltisw %0,-1";
4452 if (zero_constant (vec, mode))
4453 return "vxor %0,%0,%0";
4455 splat_vec = gen_easy_altivec_constant (vec);
4456 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4457 operands[1] = XEXP (splat_vec, 0);
4458 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4461 switch (GET_MODE (splat_vec))
4464 return "vspltisw %0,%1";
4467 return "vspltish %0,%1";
4470 return "vspltisb %0,%1";
4477 gcc_assert (TARGET_SPE);
4479 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4480 pattern of V1DI, V4HI, and V2SF.
4482 FIXME: We should probably return # and add post reload
4483 splitters for these, but this way is so easy ;-). */
4484 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4485 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4486 operands[1] = CONST_VECTOR_ELT (vec, 0);
4487 operands[2] = CONST_VECTOR_ELT (vec, 1);
4489 return "li %0,%1\n\tevmergelo %0,%0,%0";
4491 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4494 /* Initialize TARGET of vector PAIRED to VALS. */
4497 paired_expand_vector_init (rtx target, rtx vals)
4499 enum machine_mode mode = GET_MODE (target);
4500 int n_elts = GET_MODE_NUNITS (mode);
4502 rtx x, new_rtx, tmp, constant_op, op1, op2;
4505 for (i = 0; i < n_elts; ++i)
4507 x = XVECEXP (vals, 0, i);
4508 if (!CONSTANT_P (x))
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 (!CONSTANT_P (x))
4661 ++n_var, one_var = i;
4662 else if (x != CONST0_RTX (inner_mode))
4663 all_const_zero = false;
4665 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4671 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4672 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4673 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4675 /* Zero register. */
4676 emit_insn (gen_rtx_SET (VOIDmode, target,
4677 gen_rtx_XOR (mode, target, target)));
4680 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4682 /* Splat immediate. */
4683 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4688 /* Load from constant pool. */
4689 emit_move_insn (target, const_vec);
4694 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4695 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4699 rtx element = XVECEXP (vals, 0, 0);
4700 if (mode == V2DFmode)
4701 emit_insn (gen_vsx_splat_v2df (target, element));
4703 emit_insn (gen_vsx_splat_v2di (target, element));
4707 if (mode == V2DFmode)
4709 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
4710 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
4711 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4715 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
4716 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
4717 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4723 /* With single precision floating point on VSX, know that internally single
4724 precision is actually represented as a double, and either make 2 V2DF
4725 vectors, and convert these vectors to single precision, or do one
4726 conversion, and splat the result to the other elements. */
4727 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4731 rtx freg = gen_reg_rtx (V4SFmode);
4732 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4734 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4735 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4739 rtx dbl_even = gen_reg_rtx (V2DFmode);
4740 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4741 rtx flt_even = gen_reg_rtx (V4SFmode);
4742 rtx flt_odd = gen_reg_rtx (V4SFmode);
4744 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4745 copy_to_reg (XVECEXP (vals, 0, 0)),
4746 copy_to_reg (XVECEXP (vals, 0, 1))));
4747 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4748 copy_to_reg (XVECEXP (vals, 0, 2)),
4749 copy_to_reg (XVECEXP (vals, 0, 3))));
4750 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4751 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4752 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4757 /* Store value to stack temp. Load vector element. Splat. However, splat
4758 of 64-bit items is not supported on Altivec. */
4759 if (all_same && GET_MODE_SIZE (mode) <= 4)
4761 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4762 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4763 XVECEXP (vals, 0, 0));
4764 x = gen_rtx_UNSPEC (VOIDmode,
4765 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4766 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4768 gen_rtx_SET (VOIDmode,
4771 x = gen_rtx_VEC_SELECT (inner_mode, target,
4772 gen_rtx_PARALLEL (VOIDmode,
4773 gen_rtvec (1, const0_rtx)));
4774 emit_insn (gen_rtx_SET (VOIDmode, target,
4775 gen_rtx_VEC_DUPLICATE (mode, x)));
4779 /* One field is non-constant. Load constant then overwrite
4783 rtx copy = copy_rtx (vals);
4785 /* Load constant part of vector, substitute neighboring value for
4787 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4788 rs6000_expand_vector_init (target, copy);
4790 /* Insert variable. */
4791 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4795 /* Construct the vector in memory one field at a time
4796 and load the whole vector. */
4797 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4798 for (i = 0; i < n_elts; i++)
4799 emit_move_insn (adjust_address_nv (mem, inner_mode,
4800 i * GET_MODE_SIZE (inner_mode)),
4801 XVECEXP (vals, 0, i));
4802 emit_move_insn (target, mem);
4805 /* Set field ELT of TARGET to VAL. */
4808 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4810 enum machine_mode mode = GET_MODE (target);
4811 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4812 rtx reg = gen_reg_rtx (mode);
4814 int width = GET_MODE_SIZE (inner_mode);
4817 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4819 rtx (*set_func) (rtx, rtx, rtx, rtx)
4820 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4821 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4825 /* Load single variable value. */
4826 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4827 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4828 x = gen_rtx_UNSPEC (VOIDmode,
4829 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4830 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4832 gen_rtx_SET (VOIDmode,
4836 /* Linear sequence. */
4837 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4838 for (i = 0; i < 16; ++i)
4839 XVECEXP (mask, 0, i) = GEN_INT (i);
4841 /* Set permute mask to insert element into target. */
4842 for (i = 0; i < width; ++i)
4843 XVECEXP (mask, 0, elt*width + i)
4844 = GEN_INT (i + 0x10);
4845 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4846 x = gen_rtx_UNSPEC (mode,
4847 gen_rtvec (3, target, reg,
4848 force_reg (V16QImode, x)),
4850 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4853 /* Extract field ELT from VEC into TARGET. */
4856 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4858 enum machine_mode mode = GET_MODE (vec);
4859 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4862 if (VECTOR_MEM_VSX_P (mode))
4869 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
4872 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
4875 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
4880 /* Allocate mode-sized buffer. */
4881 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4883 emit_move_insn (mem, vec);
4885 /* Add offset to field within buffer matching vector element. */
4886 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
4888 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4891 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4892 implement ANDing by the mask IN. */
4894 build_mask64_2_operands (rtx in, rtx *out)
4896 #if HOST_BITS_PER_WIDE_INT >= 64
4897 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4900 gcc_assert (GET_CODE (in) == CONST_INT);
4905 /* Assume c initially something like 0x00fff000000fffff. The idea
4906 is to rotate the word so that the middle ^^^^^^ group of zeros
4907 is at the MS end and can be cleared with an rldicl mask. We then
4908 rotate back and clear off the MS ^^ group of zeros with a
4910 c = ~c; /* c == 0xff000ffffff00000 */
4911 lsb = c & -c; /* lsb == 0x0000000000100000 */
4912 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4913 c = ~c; /* c == 0x00fff000000fffff */
4914 c &= -lsb; /* c == 0x00fff00000000000 */
4915 lsb = c & -c; /* lsb == 0x0000100000000000 */
4916 c = ~c; /* c == 0xff000fffffffffff */
4917 c &= -lsb; /* c == 0xff00000000000000 */
4919 while ((lsb >>= 1) != 0)
4920 shift++; /* shift == 44 on exit from loop */
4921 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4922 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4923 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4927 /* Assume c initially something like 0xff000f0000000000. The idea
4928 is to rotate the word so that the ^^^ middle group of zeros
4929 is at the LS end and can be cleared with an rldicr mask. We then
4930 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4932 lsb = c & -c; /* lsb == 0x0000010000000000 */
4933 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4934 c = ~c; /* c == 0x00fff0ffffffffff */
4935 c &= -lsb; /* c == 0x00fff00000000000 */
4936 lsb = c & -c; /* lsb == 0x0000100000000000 */
4937 c = ~c; /* c == 0xff000fffffffffff */
4938 c &= -lsb; /* c == 0xff00000000000000 */
4940 while ((lsb >>= 1) != 0)
4941 shift++; /* shift == 44 on exit from loop */
4942 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4943 m1 >>= shift; /* m1 == 0x0000000000000fff */
4944 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4947 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4948 masks will be all 1's. We are guaranteed more than one transition. */
4949 out[0] = GEN_INT (64 - shift);
4950 out[1] = GEN_INT (m1);
4951 out[2] = GEN_INT (shift);
4952 out[3] = GEN_INT (m2);
4960 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4963 invalid_e500_subreg (rtx op, enum machine_mode mode)
4965 if (TARGET_E500_DOUBLE)
4967 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4968 subreg:TI and reg:TF. Decimal float modes are like integer
4969 modes (only low part of each register used) for this
4971 if (GET_CODE (op) == SUBREG
4972 && (mode == SImode || mode == DImode || mode == TImode
4973 || mode == DDmode || mode == TDmode)
4974 && REG_P (SUBREG_REG (op))
4975 && (GET_MODE (SUBREG_REG (op)) == DFmode
4976 || GET_MODE (SUBREG_REG (op)) == TFmode))
4979 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4981 if (GET_CODE (op) == SUBREG
4982 && (mode == DFmode || mode == TFmode)
4983 && REG_P (SUBREG_REG (op))
4984 && (GET_MODE (SUBREG_REG (op)) == DImode
4985 || GET_MODE (SUBREG_REG (op)) == TImode
4986 || GET_MODE (SUBREG_REG (op)) == DDmode
4987 || GET_MODE (SUBREG_REG (op)) == TDmode))
4992 && GET_CODE (op) == SUBREG
4994 && REG_P (SUBREG_REG (op))
4995 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5001 /* AIX increases natural record alignment to doubleword if the first
5002 field is an FP double while the FP fields remain word aligned. */
5005 rs6000_special_round_type_align (tree type, unsigned int computed,
5006 unsigned int specified)
5008 unsigned int align = MAX (computed, specified);
5009 tree field = TYPE_FIELDS (type);
5011 /* Skip all non field decls */
5012 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5013 field = DECL_CHAIN (field);
5015 if (field != NULL && field != type)
5017 type = TREE_TYPE (field);
5018 while (TREE_CODE (type) == ARRAY_TYPE)
5019 type = TREE_TYPE (type);
5021 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5022 align = MAX (align, 64);
5028 /* Darwin increases record alignment to the natural alignment of
5032 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5033 unsigned int specified)
5035 unsigned int align = MAX (computed, specified);
5037 if (TYPE_PACKED (type))
5040 /* Find the first field, looking down into aggregates. */
5042 tree field = TYPE_FIELDS (type);
5043 /* Skip all non field decls */
5044 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5045 field = DECL_CHAIN (field);
5048 /* A packed field does not contribute any extra alignment. */
5049 if (DECL_PACKED (field))
5051 type = TREE_TYPE (field);
5052 while (TREE_CODE (type) == ARRAY_TYPE)
5053 type = TREE_TYPE (type);
5054 } while (AGGREGATE_TYPE_P (type));
5056 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5057 align = MAX (align, TYPE_ALIGN (type));
5062 /* Return 1 for an operand in small memory on V.4/eabi. */
5065 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5066 enum machine_mode mode ATTRIBUTE_UNUSED)
5071 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5074 if (DEFAULT_ABI != ABI_V4)
5077 /* Vector and float memory instructions have a limited offset on the
5078 SPE, so using a vector or float variable directly as an operand is
5081 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5084 if (GET_CODE (op) == SYMBOL_REF)
5087 else if (GET_CODE (op) != CONST
5088 || GET_CODE (XEXP (op, 0)) != PLUS
5089 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5090 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5095 rtx sum = XEXP (op, 0);
5096 HOST_WIDE_INT summand;
5098 /* We have to be careful here, because it is the referenced address
5099 that must be 32k from _SDA_BASE_, not just the symbol. */
5100 summand = INTVAL (XEXP (sum, 1));
5101 if (summand < 0 || summand > g_switch_value)
5104 sym_ref = XEXP (sum, 0);
5107 return SYMBOL_REF_SMALL_P (sym_ref);
5113 /* Return true if either operand is a general purpose register. */
5116 gpr_or_gpr_p (rtx op0, rtx op1)
5118 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5119 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5123 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5126 reg_offset_addressing_ok_p (enum machine_mode mode)
5136 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5137 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5145 /* Paired vector modes. Only reg+reg addressing is valid. */
5146 if (TARGET_PAIRED_FLOAT)
5158 virtual_stack_registers_memory_p (rtx op)
5162 if (GET_CODE (op) == REG)
5163 regnum = REGNO (op);
5165 else if (GET_CODE (op) == PLUS
5166 && GET_CODE (XEXP (op, 0)) == REG
5167 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5168 regnum = REGNO (XEXP (op, 0));
5173 return (regnum >= FIRST_VIRTUAL_REGISTER
5174 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5177 /* Return true if memory accesses to OP are known to never straddle
5181 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5182 enum machine_mode mode)
5185 unsigned HOST_WIDE_INT dsize, dalign;
5187 if (GET_CODE (op) != SYMBOL_REF)
5190 decl = SYMBOL_REF_DECL (op);
5193 if (GET_MODE_SIZE (mode) == 0)
5196 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5197 replacing memory addresses with an anchor plus offset. We
5198 could find the decl by rummaging around in the block->objects
5199 VEC for the given offset but that seems like too much work. */
5201 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5202 && SYMBOL_REF_ANCHOR_P (op)
5203 && SYMBOL_REF_BLOCK (op) != NULL)
5205 struct object_block *block = SYMBOL_REF_BLOCK (op);
5206 HOST_WIDE_INT lsb, mask;
5208 /* Given the alignment of the block.. */
5209 dalign = block->alignment;
5210 mask = dalign / BITS_PER_UNIT - 1;
5212 /* ..and the combined offset of the anchor and any offset
5213 to this block object.. */
5214 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5215 lsb = offset & -offset;
5217 /* ..find how many bits of the alignment we know for the
5222 return dalign >= GET_MODE_SIZE (mode);
5227 if (TREE_CODE (decl) == FUNCTION_DECL)
5230 if (!DECL_SIZE_UNIT (decl))
5233 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5236 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5240 dalign = DECL_ALIGN_UNIT (decl);
5241 return dalign >= dsize;
5244 type = TREE_TYPE (decl);
5246 if (TREE_CODE (decl) == STRING_CST)
5247 dsize = TREE_STRING_LENGTH (decl);
5248 else if (TYPE_SIZE_UNIT (type)
5249 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5250 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5256 dalign = TYPE_ALIGN (type);
5257 if (CONSTANT_CLASS_P (decl))
5258 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5260 dalign = DATA_ALIGNMENT (decl, dalign);
5261 dalign /= BITS_PER_UNIT;
5262 return dalign >= dsize;
5266 constant_pool_expr_p (rtx op)
5270 split_const (op, &base, &offset);
5271 return (GET_CODE (base) == SYMBOL_REF
5272 && CONSTANT_POOL_ADDRESS_P (base)
5273 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5276 static rtx tocrel_base, tocrel_offset;
5279 toc_relative_expr_p (rtx op)
5281 if (GET_CODE (op) != CONST)
5284 split_const (op, &tocrel_base, &tocrel_offset);
5285 return (GET_CODE (tocrel_base) == UNSPEC
5286 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5289 /* Return true if X is a constant pool address, and also for cmodel=medium
5290 if X is a toc-relative address known to be offsettable within MODE. */
5293 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5297 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5298 && GET_CODE (XEXP (x, 0)) == REG
5299 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5300 || ((TARGET_MINIMAL_TOC
5301 || TARGET_CMODEL != CMODEL_SMALL)
5302 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5303 && toc_relative_expr_p (XEXP (x, 1))
5304 && (TARGET_CMODEL != CMODEL_MEDIUM
5305 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5307 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5308 INTVAL (tocrel_offset), mode)));
5312 legitimate_small_data_p (enum machine_mode mode, rtx x)
5314 return (DEFAULT_ABI == ABI_V4
5315 && !flag_pic && !TARGET_TOC
5316 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5317 && small_data_operand (x, mode));
5320 /* SPE offset addressing is limited to 5-bits worth of double words. */
5321 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5324 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5326 unsigned HOST_WIDE_INT offset, extra;
5328 if (GET_CODE (x) != PLUS)
5330 if (GET_CODE (XEXP (x, 0)) != REG)
5332 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5334 if (!reg_offset_addressing_ok_p (mode))
5335 return virtual_stack_registers_memory_p (x);
5336 if (legitimate_constant_pool_address_p (x, mode, strict))
5338 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5341 offset = INTVAL (XEXP (x, 1));
5349 /* SPE vector modes. */
5350 return SPE_CONST_OFFSET_OK (offset);
5353 if (TARGET_E500_DOUBLE)
5354 return SPE_CONST_OFFSET_OK (offset);
5356 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5358 if (VECTOR_MEM_VSX_P (DFmode))
5363 /* On e500v2, we may have:
5365 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5367 Which gets addressed with evldd instructions. */
5368 if (TARGET_E500_DOUBLE)
5369 return SPE_CONST_OFFSET_OK (offset);
5371 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5373 else if (offset & 3)
5378 if (TARGET_E500_DOUBLE)
5379 return (SPE_CONST_OFFSET_OK (offset)
5380 && SPE_CONST_OFFSET_OK (offset + 8));
5384 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5386 else if (offset & 3)
5397 return (offset < 0x10000) && (offset + extra < 0x10000);
5401 legitimate_indexed_address_p (rtx x, int strict)
5405 if (GET_CODE (x) != PLUS)
5411 /* Recognize the rtl generated by reload which we know will later be
5412 replaced with proper base and index regs. */
5414 && reload_in_progress
5415 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5419 return (REG_P (op0) && REG_P (op1)
5420 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5421 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5422 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5423 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5427 avoiding_indexed_address_p (enum machine_mode mode)
5429 /* Avoid indexed addressing for modes that have non-indexed
5430 load/store instruction forms. */
5431 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5435 legitimate_indirect_address_p (rtx x, int strict)
5437 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5441 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5443 if (!TARGET_MACHO || !flag_pic
5444 || mode != SImode || GET_CODE (x) != MEM)
5448 if (GET_CODE (x) != LO_SUM)
5450 if (GET_CODE (XEXP (x, 0)) != REG)
5452 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5456 return CONSTANT_P (x);
5460 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5462 if (GET_CODE (x) != LO_SUM)
5464 if (GET_CODE (XEXP (x, 0)) != REG)
5466 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5468 /* Restrict addressing for DI because of our SUBREG hackery. */
5469 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5470 || mode == DDmode || mode == TDmode
5475 if (TARGET_ELF || TARGET_MACHO)
5477 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5481 if (GET_MODE_NUNITS (mode) != 1)
5483 if (GET_MODE_BITSIZE (mode) > 64
5484 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5485 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5486 && (mode == DFmode || mode == DDmode))))
5489 return CONSTANT_P (x);
5496 /* Try machine-dependent ways of modifying an illegitimate address
5497 to be legitimate. If we find one, return the new, valid address.
5498 This is used from only one place: `memory_address' in explow.c.
5500 OLDX is the address as it was before break_out_memory_refs was
5501 called. In some cases it is useful to look at this to decide what
5504 It is always safe for this function to do nothing. It exists to
5505 recognize opportunities to optimize the output.
5507 On RS/6000, first check for the sum of a register with a constant
5508 integer that is out of range. If so, generate code to add the
5509 constant with the low-order 16 bits masked to the register and force
5510 this result into another register (this can be done with `cau').
5511 Then generate an address of REG+(CONST&0xffff), allowing for the
5512 possibility of bit 16 being a one.
5514 Then check for the sum of a register and something not constant, try to
5515 load the other things into a register and return the sum. */
5518 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5519 enum machine_mode mode)
5521 unsigned int extra = 0;
5523 if (!reg_offset_addressing_ok_p (mode))
5525 if (virtual_stack_registers_memory_p (x))
5528 /* In theory we should not be seeing addresses of the form reg+0,
5529 but just in case it is generated, optimize it away. */
5530 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5531 return force_reg (Pmode, XEXP (x, 0));
5533 /* Make sure both operands are registers. */
5534 else if (GET_CODE (x) == PLUS)
5535 return gen_rtx_PLUS (Pmode,
5536 force_reg (Pmode, XEXP (x, 0)),
5537 force_reg (Pmode, XEXP (x, 1)));
5539 return force_reg (Pmode, x);
5541 if (GET_CODE (x) == SYMBOL_REF)
5543 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5545 return rs6000_legitimize_tls_address (x, model);
5555 if (!TARGET_POWERPC64)
5563 extra = TARGET_POWERPC64 ? 8 : 12;
5569 if (GET_CODE (x) == PLUS
5570 && GET_CODE (XEXP (x, 0)) == REG
5571 && GET_CODE (XEXP (x, 1)) == CONST_INT
5572 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5574 && !((TARGET_POWERPC64
5575 && (mode == DImode || mode == TImode)
5576 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5577 || SPE_VECTOR_MODE (mode)
5578 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5579 || mode == DImode || mode == DDmode
5580 || mode == TDmode))))
5582 HOST_WIDE_INT high_int, low_int;
5584 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5585 if (low_int >= 0x8000 - extra)
5587 high_int = INTVAL (XEXP (x, 1)) - low_int;
5588 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5589 GEN_INT (high_int)), 0);
5590 return plus_constant (sum, low_int);
5592 else if (GET_CODE (x) == PLUS
5593 && GET_CODE (XEXP (x, 0)) == REG
5594 && GET_CODE (XEXP (x, 1)) != CONST_INT
5595 && GET_MODE_NUNITS (mode) == 1
5596 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5598 || ((mode != DImode && mode != DFmode && mode != DDmode)
5599 || (TARGET_E500_DOUBLE && mode != DDmode)))
5600 && (TARGET_POWERPC64 || mode != DImode)
5601 && !avoiding_indexed_address_p (mode)
5606 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5607 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5609 else if (SPE_VECTOR_MODE (mode)
5610 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5611 || mode == DDmode || mode == TDmode
5612 || mode == DImode)))
5616 /* We accept [reg + reg] and [reg + OFFSET]. */
5618 if (GET_CODE (x) == PLUS)
5620 rtx op1 = XEXP (x, 0);
5621 rtx op2 = XEXP (x, 1);
5624 op1 = force_reg (Pmode, op1);
5626 if (GET_CODE (op2) != REG
5627 && (GET_CODE (op2) != CONST_INT
5628 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5629 || (GET_MODE_SIZE (mode) > 8
5630 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5631 op2 = force_reg (Pmode, op2);
5633 /* We can't always do [reg + reg] for these, because [reg +
5634 reg + offset] is not a legitimate addressing mode. */
5635 y = gen_rtx_PLUS (Pmode, op1, op2);
5637 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5638 return force_reg (Pmode, y);
5643 return force_reg (Pmode, x);
5649 && GET_CODE (x) != CONST_INT
5650 && GET_CODE (x) != CONST_DOUBLE
5652 && GET_MODE_NUNITS (mode) == 1
5653 && (GET_MODE_BITSIZE (mode) <= 32
5654 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5655 && (mode == DFmode || mode == DDmode))))
5657 rtx reg = gen_reg_rtx (Pmode);
5658 emit_insn (gen_elf_high (reg, x));
5659 return gen_rtx_LO_SUM (Pmode, reg, x);
5661 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5664 && ! MACHO_DYNAMIC_NO_PIC_P
5666 && GET_CODE (x) != CONST_INT
5667 && GET_CODE (x) != CONST_DOUBLE
5669 && GET_MODE_NUNITS (mode) == 1
5670 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5671 || (mode != DFmode && mode != DDmode))
5675 rtx reg = gen_reg_rtx (Pmode);
5676 emit_insn (gen_macho_high (reg, x));
5677 return gen_rtx_LO_SUM (Pmode, reg, x);
5680 && GET_CODE (x) == SYMBOL_REF
5681 && constant_pool_expr_p (x)
5682 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5684 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5685 return create_TOC_reference (x, reg);
5691 /* Debug version of rs6000_legitimize_address. */
5693 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5699 ret = rs6000_legitimize_address (x, oldx, mode);
5700 insns = get_insns ();
5706 "\nrs6000_legitimize_address: mode %s, old code %s, "
5707 "new code %s, modified\n",
5708 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5709 GET_RTX_NAME (GET_CODE (ret)));
5711 fprintf (stderr, "Original address:\n");
5714 fprintf (stderr, "oldx:\n");
5717 fprintf (stderr, "New address:\n");
5722 fprintf (stderr, "Insns added:\n");
5723 debug_rtx_list (insns, 20);
5729 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5730 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5741 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5742 We need to emit DTP-relative relocations. */
5745 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5750 fputs ("\t.long\t", file);
5753 fputs (DOUBLE_INT_ASM_OP, file);
5758 output_addr_const (file, x);
5759 fputs ("@dtprel+0x8000", file);
5762 /* In the name of slightly smaller debug output, and to cater to
5763 general assembler lossage, recognize various UNSPEC sequences
5764 and turn them back into a direct symbol reference. */
5767 rs6000_delegitimize_address (rtx orig_x)
5771 orig_x = delegitimize_mem_from_attrs (orig_x);
5776 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
5777 && GET_CODE (XEXP (x, 1)) == CONST)
5779 rtx offset = NULL_RTX;
5781 y = XEXP (XEXP (x, 1), 0);
5782 if (GET_CODE (y) == PLUS
5783 && GET_MODE (y) == Pmode
5784 && CONST_INT_P (XEXP (y, 1)))
5786 offset = XEXP (y, 1);
5789 if (GET_CODE (y) == UNSPEC
5790 && XINT (y, 1) == UNSPEC_TOCREL
5791 && ((GET_CODE (XEXP (x, 0)) == REG
5792 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5793 || TARGET_MINIMAL_TOC
5794 || TARGET_CMODEL != CMODEL_SMALL))
5795 || (TARGET_CMODEL != CMODEL_SMALL
5796 && GET_CODE (XEXP (x, 0)) == CONST
5797 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
5798 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
5799 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
5800 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
5801 && rtx_equal_p (XEXP (x, 1),
5802 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
5804 y = XVECEXP (y, 0, 0);
5805 if (offset != NULL_RTX)
5806 y = gen_rtx_PLUS (Pmode, y, offset);
5807 if (!MEM_P (orig_x))
5810 return replace_equiv_address_nv (orig_x, y);
5815 && GET_CODE (orig_x) == LO_SUM
5816 && GET_CODE (XEXP (orig_x, 1)) == CONST)
5818 y = XEXP (XEXP (orig_x, 1), 0);
5819 if (GET_CODE (y) == UNSPEC
5820 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5821 return XVECEXP (y, 0, 0);
5827 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5829 static GTY(()) rtx rs6000_tls_symbol;
5831 rs6000_tls_get_addr (void)
5833 if (!rs6000_tls_symbol)
5834 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5836 return rs6000_tls_symbol;
5839 /* Construct the SYMBOL_REF for TLS GOT references. */
5841 static GTY(()) rtx rs6000_got_symbol;
5843 rs6000_got_sym (void)
5845 if (!rs6000_got_symbol)
5847 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5848 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5849 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5852 return rs6000_got_symbol;
5855 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5856 this (thread-local) address. */
5859 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5863 dest = gen_reg_rtx (Pmode);
5864 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5870 tlsreg = gen_rtx_REG (Pmode, 13);
5871 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5875 tlsreg = gen_rtx_REG (Pmode, 2);
5876 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5880 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5884 tmp = gen_reg_rtx (Pmode);
5887 tlsreg = gen_rtx_REG (Pmode, 13);
5888 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5892 tlsreg = gen_rtx_REG (Pmode, 2);
5893 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5897 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5899 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5904 rtx r3, got, tga, tmp1, tmp2, call_insn;
5906 /* We currently use relocations like @got@tlsgd for tls, which
5907 means the linker will handle allocation of tls entries, placing
5908 them in the .got section. So use a pointer to the .got section,
5909 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5910 or to secondary GOT sections used by 32-bit -fPIC. */
5912 got = gen_rtx_REG (Pmode, 2);
5916 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5919 rtx gsym = rs6000_got_sym ();
5920 got = gen_reg_rtx (Pmode);
5922 rs6000_emit_move (got, gsym, Pmode);
5927 tmp1 = gen_reg_rtx (Pmode);
5928 tmp2 = gen_reg_rtx (Pmode);
5929 mem = gen_const_mem (Pmode, tmp1);
5930 lab = gen_label_rtx ();
5931 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5932 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5933 emit_move_insn (tmp2, mem);
5934 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5935 set_unique_reg_note (last, REG_EQUAL, gsym);
5940 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5942 tga = rs6000_tls_get_addr ();
5943 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
5944 1, const0_rtx, Pmode);
5946 r3 = gen_rtx_REG (Pmode, 3);
5947 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5948 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5949 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5950 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5951 else if (DEFAULT_ABI == ABI_V4)
5952 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5955 call_insn = last_call_insn ();
5956 PATTERN (call_insn) = insn;
5957 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5958 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5959 pic_offset_table_rtx);
5961 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5963 tga = rs6000_tls_get_addr ();
5964 tmp1 = gen_reg_rtx (Pmode);
5965 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
5966 1, const0_rtx, Pmode);
5968 r3 = gen_rtx_REG (Pmode, 3);
5969 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5970 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5971 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5972 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5973 else if (DEFAULT_ABI == ABI_V4)
5974 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5977 call_insn = last_call_insn ();
5978 PATTERN (call_insn) = insn;
5979 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5980 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5981 pic_offset_table_rtx);
5983 if (rs6000_tls_size == 16)
5986 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5988 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5990 else if (rs6000_tls_size == 32)
5992 tmp2 = gen_reg_rtx (Pmode);
5994 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5996 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5999 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6001 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6005 tmp2 = gen_reg_rtx (Pmode);
6007 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6009 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6011 insn = gen_rtx_SET (Pmode, dest,
6012 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6018 /* IE, or 64-bit offset LE. */
6019 tmp2 = gen_reg_rtx (Pmode);
6021 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6023 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6026 insn = gen_tls_tls_64 (dest, tmp2, addr);
6028 insn = gen_tls_tls_32 (dest, tmp2, addr);
6036 /* Return 1 if X contains a thread-local symbol. */
6039 rs6000_tls_referenced_p (rtx x)
6041 if (! TARGET_HAVE_TLS)
6044 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6047 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6050 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6052 if (GET_CODE (x) == CONST
6053 && GET_CODE (XEXP (x, 0)) == PLUS
6054 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6057 return rs6000_tls_referenced_p (x);
6060 /* Return 1 if *X is a thread-local symbol. This is the same as
6061 rs6000_tls_symbol_ref except for the type of the unused argument. */
6064 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6066 return RS6000_SYMBOL_REF_TLS_P (*x);
6069 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6070 replace the input X, or the original X if no replacement is called for.
6071 The output parameter *WIN is 1 if the calling macro should goto WIN,
6074 For RS/6000, we wish to handle large displacements off a base
6075 register by splitting the addend across an addiu/addis and the mem insn.
6076 This cuts number of extra insns needed from 3 to 1.
6078 On Darwin, we use this to generate code for floating point constants.
6079 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6080 The Darwin code is inside #if TARGET_MACHO because only then are the
6081 machopic_* functions defined. */
6083 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6084 int opnum, int type,
6085 int ind_levels ATTRIBUTE_UNUSED, int *win)
6087 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6089 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6090 DFmode/DImode MEM. */
6093 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6094 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6095 reg_offset_p = false;
6097 /* We must recognize output that we have already generated ourselves. */
6098 if (GET_CODE (x) == PLUS
6099 && GET_CODE (XEXP (x, 0)) == PLUS
6100 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6101 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6102 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6104 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6105 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6106 opnum, (enum reload_type)type);
6111 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6112 if (GET_CODE (x) == LO_SUM
6113 && GET_CODE (XEXP (x, 0)) == HIGH)
6115 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6116 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6117 opnum, (enum reload_type)type);
6123 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6124 && GET_CODE (x) == LO_SUM
6125 && GET_CODE (XEXP (x, 0)) == PLUS
6126 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6127 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6128 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6129 && machopic_operand_p (XEXP (x, 1)))
6131 /* Result of previous invocation of this function on Darwin
6132 floating point constant. */
6133 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6134 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6135 opnum, (enum reload_type)type);
6141 if (TARGET_CMODEL != CMODEL_SMALL
6142 && GET_CODE (x) == LO_SUM
6143 && GET_CODE (XEXP (x, 0)) == PLUS
6144 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6145 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6146 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6147 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6148 && GET_CODE (XEXP (x, 1)) == CONST
6149 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6150 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6151 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6153 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6154 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6155 opnum, (enum reload_type) type);
6160 /* Force ld/std non-word aligned offset into base register by wrapping
6162 if (GET_CODE (x) == PLUS
6163 && GET_CODE (XEXP (x, 0)) == REG
6164 && REGNO (XEXP (x, 0)) < 32
6165 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6166 && GET_CODE (XEXP (x, 1)) == CONST_INT
6168 && (INTVAL (XEXP (x, 1)) & 3) != 0
6169 && VECTOR_MEM_NONE_P (mode)
6170 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6171 && TARGET_POWERPC64)
6173 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6174 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6175 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6176 opnum, (enum reload_type) type);
6181 if (GET_CODE (x) == PLUS
6182 && GET_CODE (XEXP (x, 0)) == REG
6183 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6184 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6185 && GET_CODE (XEXP (x, 1)) == CONST_INT
6187 && !SPE_VECTOR_MODE (mode)
6188 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6189 || mode == DDmode || mode == TDmode
6191 && VECTOR_MEM_NONE_P (mode))
6193 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6194 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6196 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6198 /* Check for 32-bit overflow. */
6199 if (high + low != val)
6205 /* Reload the high part into a base reg; leave the low part
6206 in the mem directly. */
6208 x = gen_rtx_PLUS (GET_MODE (x),
6209 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6213 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6214 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6215 opnum, (enum reload_type)type);
6220 if (GET_CODE (x) == SYMBOL_REF
6222 && VECTOR_MEM_NONE_P (mode)
6223 && !SPE_VECTOR_MODE (mode)
6225 && DEFAULT_ABI == ABI_DARWIN
6226 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6228 && DEFAULT_ABI == ABI_V4
6231 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6232 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6236 && (mode != DImode || TARGET_POWERPC64)
6237 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6238 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6243 rtx offset = machopic_gen_offset (x);
6244 x = gen_rtx_LO_SUM (GET_MODE (x),
6245 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6246 gen_rtx_HIGH (Pmode, offset)), offset);
6250 x = gen_rtx_LO_SUM (GET_MODE (x),
6251 gen_rtx_HIGH (Pmode, x), x);
6253 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6254 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6255 opnum, (enum reload_type)type);
6260 /* Reload an offset address wrapped by an AND that represents the
6261 masking of the lower bits. Strip the outer AND and let reload
6262 convert the offset address into an indirect address. For VSX,
6263 force reload to create the address with an AND in a separate
6264 register, because we can't guarantee an altivec register will
6266 if (VECTOR_MEM_ALTIVEC_P (mode)
6267 && GET_CODE (x) == AND
6268 && GET_CODE (XEXP (x, 0)) == PLUS
6269 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6270 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6271 && GET_CODE (XEXP (x, 1)) == CONST_INT
6272 && INTVAL (XEXP (x, 1)) == -16)
6281 && GET_CODE (x) == SYMBOL_REF
6282 && constant_pool_expr_p (x)
6283 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6285 x = create_TOC_reference (x, NULL_RTX);
6286 if (TARGET_CMODEL != CMODEL_SMALL)
6287 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6288 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6289 opnum, (enum reload_type) type);
6297 /* Debug version of rs6000_legitimize_reload_address. */
6299 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6300 int opnum, int type,
6301 int ind_levels, int *win)
6303 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6306 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6307 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6308 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6312 fprintf (stderr, "Same address returned\n");
6314 fprintf (stderr, "NULL returned\n");
6317 fprintf (stderr, "New address:\n");
6324 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6325 that is a valid memory address for an instruction.
6326 The MODE argument is the machine mode for the MEM expression
6327 that wants to use this address.
6329 On the RS/6000, there are four valid address: a SYMBOL_REF that
6330 refers to a constant pool entry of an address (or the sum of it
6331 plus a constant), a short (16-bit signed) constant plus a register,
6332 the sum of two registers, or a register indirect, possibly with an
6333 auto-increment. For DFmode, DDmode and DImode with a constant plus
6334 register, we must ensure that both words are addressable or PowerPC64
6335 with offset word aligned.
6337 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6338 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6339 because adjacent memory cells are accessed by adding word-sized offsets
6340 during assembly output. */
6342 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6344 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6346 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6347 if (VECTOR_MEM_ALTIVEC_P (mode)
6348 && GET_CODE (x) == AND
6349 && GET_CODE (XEXP (x, 1)) == CONST_INT
6350 && INTVAL (XEXP (x, 1)) == -16)
6353 if (RS6000_SYMBOL_REF_TLS_P (x))
6355 if (legitimate_indirect_address_p (x, reg_ok_strict))
6357 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6358 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6359 && !SPE_VECTOR_MODE (mode)
6362 /* Restrict addressing for DI because of our SUBREG hackery. */
6363 && !(TARGET_E500_DOUBLE
6364 && (mode == DFmode || mode == DDmode || mode == DImode))
6366 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6368 if (virtual_stack_registers_memory_p (x))
6370 if (reg_offset_p && legitimate_small_data_p (mode, x))
6373 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6375 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6378 && GET_CODE (x) == PLUS
6379 && GET_CODE (XEXP (x, 0)) == REG
6380 && (XEXP (x, 0) == virtual_stack_vars_rtx
6381 || XEXP (x, 0) == arg_pointer_rtx)
6382 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6384 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6389 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6391 || (mode != DFmode && mode != DDmode)
6392 || (TARGET_E500_DOUBLE && mode != DDmode))
6393 && (TARGET_POWERPC64 || mode != DImode)
6394 && !avoiding_indexed_address_p (mode)
6395 && legitimate_indexed_address_p (x, reg_ok_strict))
6397 if (GET_CODE (x) == PRE_MODIFY
6401 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6403 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6404 && (TARGET_POWERPC64 || mode != DImode)
6405 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6406 && !SPE_VECTOR_MODE (mode)
6407 /* Restrict addressing for DI because of our SUBREG hackery. */
6408 && !(TARGET_E500_DOUBLE
6409 && (mode == DFmode || mode == DDmode || mode == DImode))
6411 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6412 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6413 || (!avoiding_indexed_address_p (mode)
6414 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6415 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6417 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6422 /* Debug version of rs6000_legitimate_address_p. */
6424 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6427 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6429 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6430 "strict = %d, code = %s\n",
6431 ret ? "true" : "false",
6432 GET_MODE_NAME (mode),
6434 GET_RTX_NAME (GET_CODE (x)));
6440 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6443 rs6000_mode_dependent_address_p (const_rtx addr)
6445 return rs6000_mode_dependent_address_ptr (addr);
6448 /* Go to LABEL if ADDR (a legitimate address expression)
6449 has an effect that depends on the machine mode it is used for.
6451 On the RS/6000 this is true of all integral offsets (since AltiVec
6452 and VSX modes don't allow them) or is a pre-increment or decrement.
6454 ??? Except that due to conceptual problems in offsettable_address_p
6455 we can't really report the problems of integral offsets. So leave
6456 this assuming that the adjustable offset must be valid for the
6457 sub-words of a TFmode operand, which is what we had before. */
6460 rs6000_mode_dependent_address (const_rtx addr)
6462 switch (GET_CODE (addr))
6465 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6466 is considered a legitimate address before reload, so there
6467 are no offset restrictions in that case. Note that this
6468 condition is safe in strict mode because any address involving
6469 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6470 been rejected as illegitimate. */
6471 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6472 && XEXP (addr, 0) != arg_pointer_rtx
6473 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6475 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6476 return val + 12 + 0x8000 >= 0x10000;
6481 /* Anything in the constant pool is sufficiently aligned that
6482 all bytes have the same high part address. */
6483 return !legitimate_constant_pool_address_p (addr, QImode, false);
6485 /* Auto-increment cases are now treated generically in recog.c. */
6487 return TARGET_UPDATE;
6489 /* AND is only allowed in Altivec loads. */
6500 /* Debug version of rs6000_mode_dependent_address. */
6502 rs6000_debug_mode_dependent_address (const_rtx addr)
6504 bool ret = rs6000_mode_dependent_address (addr);
6506 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6507 ret ? "true" : "false");
6513 /* Implement FIND_BASE_TERM. */
6516 rs6000_find_base_term (rtx op)
6520 split_const (op, &base, &offset);
6521 if (GET_CODE (base) == UNSPEC)
6522 switch (XINT (base, 1))
6525 case UNSPEC_MACHOPIC_OFFSET:
6526 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6527 for aliasing purposes. */
6528 return XVECEXP (base, 0, 0);
6534 /* More elaborate version of recog's offsettable_memref_p predicate
6535 that works around the ??? note of rs6000_mode_dependent_address.
6536 In particular it accepts
6538 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6540 in 32-bit mode, that the recog predicate rejects. */
6543 rs6000_offsettable_memref_p (rtx op)
6548 /* First mimic offsettable_memref_p. */
6549 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6552 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6553 the latter predicate knows nothing about the mode of the memory
6554 reference and, therefore, assumes that it is the largest supported
6555 mode (TFmode). As a consequence, legitimate offsettable memory
6556 references are rejected. rs6000_legitimate_offset_address_p contains
6557 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6558 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6561 /* Change register usage conditional on target flags. */
6563 rs6000_conditional_register_usage (void)
6567 if (TARGET_DEBUG_TARGET)
6568 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6570 /* Set MQ register fixed (already call_used) if not POWER
6571 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6576 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6578 fixed_regs[13] = call_used_regs[13]
6579 = call_really_used_regs[13] = 1;
6581 /* Conditionally disable FPRs. */
6582 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6583 for (i = 32; i < 64; i++)
6584 fixed_regs[i] = call_used_regs[i]
6585 = call_really_used_regs[i] = 1;
6587 /* The TOC register is not killed across calls in a way that is
6588 visible to the compiler. */
6589 if (DEFAULT_ABI == ABI_AIX)
6590 call_really_used_regs[2] = 0;
6592 if (DEFAULT_ABI == ABI_V4
6593 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6595 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6597 if (DEFAULT_ABI == ABI_V4
6598 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6600 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6601 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6602 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6604 if (DEFAULT_ABI == ABI_DARWIN
6605 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6606 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6607 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6608 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6610 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6611 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6612 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6616 global_regs[SPEFSCR_REGNO] = 1;
6617 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6618 registers in prologues and epilogues. We no longer use r14
6619 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6620 pool for link-compatibility with older versions of GCC. Once
6621 "old" code has died out, we can return r14 to the allocation
6624 = call_used_regs[14]
6625 = call_really_used_regs[14] = 1;
6628 if (!TARGET_ALTIVEC && !TARGET_VSX)
6630 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6631 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6632 call_really_used_regs[VRSAVE_REGNO] = 1;
6635 if (TARGET_ALTIVEC || TARGET_VSX)
6636 global_regs[VSCR_REGNO] = 1;
6638 if (TARGET_ALTIVEC_ABI)
6640 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6641 call_used_regs[i] = call_really_used_regs[i] = 1;
6643 /* AIX reserves VR20:31 in non-extended ABI mode. */
6645 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6646 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6650 /* Try to output insns to set TARGET equal to the constant C if it can
6651 be done in less than N insns. Do all computations in MODE.
6652 Returns the place where the output has been placed if it can be
6653 done and the insns have been emitted. If it would take more than N
6654 insns, zero is returned and no insns and emitted. */
6657 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6658 rtx source, int n ATTRIBUTE_UNUSED)
6660 rtx result, insn, set;
6661 HOST_WIDE_INT c0, c1;
6668 dest = gen_reg_rtx (mode);
6669 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6673 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6675 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6676 GEN_INT (INTVAL (source)
6677 & (~ (HOST_WIDE_INT) 0xffff))));
6678 emit_insn (gen_rtx_SET (VOIDmode, dest,
6679 gen_rtx_IOR (SImode, copy_rtx (result),
6680 GEN_INT (INTVAL (source) & 0xffff))));
6685 switch (GET_CODE (source))
6688 c0 = INTVAL (source);
6693 #if HOST_BITS_PER_WIDE_INT >= 64
6694 c0 = CONST_DOUBLE_LOW (source);
6697 c0 = CONST_DOUBLE_LOW (source);
6698 c1 = CONST_DOUBLE_HIGH (source);
6706 result = rs6000_emit_set_long_const (dest, c0, c1);
6713 insn = get_last_insn ();
6714 set = single_set (insn);
6715 if (! CONSTANT_P (SET_SRC (set)))
6716 set_unique_reg_note (insn, REG_EQUAL, source);
6721 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6722 fall back to a straight forward decomposition. We do this to avoid
6723 exponential run times encountered when looking for longer sequences
6724 with rs6000_emit_set_const. */
6726 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6728 if (!TARGET_POWERPC64)
6730 rtx operand1, operand2;
6732 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6734 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6736 emit_move_insn (operand1, GEN_INT (c1));
6737 emit_move_insn (operand2, GEN_INT (c2));
6741 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6744 ud2 = (c1 & 0xffff0000) >> 16;
6745 #if HOST_BITS_PER_WIDE_INT >= 64
6749 ud4 = (c2 & 0xffff0000) >> 16;
6751 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6752 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6755 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6757 emit_move_insn (dest, GEN_INT (ud1));
6760 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6761 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6764 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6767 emit_move_insn (dest, GEN_INT (ud2 << 16));
6769 emit_move_insn (copy_rtx (dest),
6770 gen_rtx_IOR (DImode, copy_rtx (dest),
6773 else if (ud3 == 0 && ud4 == 0)
6775 gcc_assert (ud2 & 0x8000);
6776 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6779 emit_move_insn (copy_rtx (dest),
6780 gen_rtx_IOR (DImode, copy_rtx (dest),
6782 emit_move_insn (copy_rtx (dest),
6783 gen_rtx_ZERO_EXTEND (DImode,
6784 gen_lowpart (SImode,
6787 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6788 || (ud4 == 0 && ! (ud3 & 0x8000)))
6791 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6794 emit_move_insn (dest, GEN_INT (ud3 << 16));
6797 emit_move_insn (copy_rtx (dest),
6798 gen_rtx_IOR (DImode, copy_rtx (dest),
6800 emit_move_insn (copy_rtx (dest),
6801 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6804 emit_move_insn (copy_rtx (dest),
6805 gen_rtx_IOR (DImode, copy_rtx (dest),
6811 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6814 emit_move_insn (dest, GEN_INT (ud4 << 16));
6817 emit_move_insn (copy_rtx (dest),
6818 gen_rtx_IOR (DImode, copy_rtx (dest),
6821 emit_move_insn (copy_rtx (dest),
6822 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6825 emit_move_insn (copy_rtx (dest),
6826 gen_rtx_IOR (DImode, copy_rtx (dest),
6827 GEN_INT (ud2 << 16)));
6829 emit_move_insn (copy_rtx (dest),
6830 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6836 /* Helper for the following. Get rid of [r+r] memory refs
6837 in cases where it won't work (TImode, TFmode, TDmode). */
6840 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6842 if (reload_in_progress)
6845 if (GET_CODE (operands[0]) == MEM
6846 && GET_CODE (XEXP (operands[0], 0)) != REG
6847 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
6848 GET_MODE (operands[0]), false))
6850 = replace_equiv_address (operands[0],
6851 copy_addr_to_reg (XEXP (operands[0], 0)));
6853 if (GET_CODE (operands[1]) == MEM
6854 && GET_CODE (XEXP (operands[1], 0)) != REG
6855 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
6856 GET_MODE (operands[1]), false))
6858 = replace_equiv_address (operands[1],
6859 copy_addr_to_reg (XEXP (operands[1], 0)));
6862 /* Emit a move from SOURCE to DEST in mode MODE. */
6864 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6868 operands[1] = source;
6870 if (TARGET_DEBUG_ADDR)
6873 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6874 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6875 GET_MODE_NAME (mode),
6878 can_create_pseudo_p ());
6880 fprintf (stderr, "source:\n");
6884 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6885 if (GET_CODE (operands[1]) == CONST_DOUBLE
6886 && ! FLOAT_MODE_P (mode)
6887 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6889 /* FIXME. This should never happen. */
6890 /* Since it seems that it does, do the safe thing and convert
6892 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6894 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6895 || FLOAT_MODE_P (mode)
6896 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6897 || CONST_DOUBLE_LOW (operands[1]) < 0)
6898 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6899 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6901 /* Check if GCC is setting up a block move that will end up using FP
6902 registers as temporaries. We must make sure this is acceptable. */
6903 if (GET_CODE (operands[0]) == MEM
6904 && GET_CODE (operands[1]) == MEM
6906 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6907 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6908 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6909 ? 32 : MEM_ALIGN (operands[0])))
6910 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6912 : MEM_ALIGN (operands[1]))))
6913 && ! MEM_VOLATILE_P (operands [0])
6914 && ! MEM_VOLATILE_P (operands [1]))
6916 emit_move_insn (adjust_address (operands[0], SImode, 0),
6917 adjust_address (operands[1], SImode, 0));
6918 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6919 adjust_address (copy_rtx (operands[1]), SImode, 4));
6923 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6924 && !gpc_reg_operand (operands[1], mode))
6925 operands[1] = force_reg (mode, operands[1]);
6927 if (mode == SFmode && ! TARGET_POWERPC
6928 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6929 && GET_CODE (operands[0]) == MEM)
6933 if (reload_in_progress || reload_completed)
6934 regnum = true_regnum (operands[1]);
6935 else if (GET_CODE (operands[1]) == REG)
6936 regnum = REGNO (operands[1]);
6940 /* If operands[1] is a register, on POWER it may have
6941 double-precision data in it, so truncate it to single
6943 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6946 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6947 : gen_reg_rtx (mode));
6948 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6949 operands[1] = newreg;
6953 /* Recognize the case where operand[1] is a reference to thread-local
6954 data and load its address to a register. */
6955 if (rs6000_tls_referenced_p (operands[1]))
6957 enum tls_model model;
6958 rtx tmp = operands[1];
6961 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6963 addend = XEXP (XEXP (tmp, 0), 1);
6964 tmp = XEXP (XEXP (tmp, 0), 0);
6967 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6968 model = SYMBOL_REF_TLS_MODEL (tmp);
6969 gcc_assert (model != 0);
6971 tmp = rs6000_legitimize_tls_address (tmp, model);
6974 tmp = gen_rtx_PLUS (mode, tmp, addend);
6975 tmp = force_operand (tmp, operands[0]);
6980 /* Handle the case where reload calls us with an invalid address. */
6981 if (reload_in_progress && mode == Pmode
6982 && (! general_operand (operands[1], mode)
6983 || ! nonimmediate_operand (operands[0], mode)))
6986 /* 128-bit constant floating-point values on Darwin should really be
6987 loaded as two parts. */
6988 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6989 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6991 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6992 know how to get a DFmode SUBREG of a TFmode. */
6993 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6994 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6995 simplify_gen_subreg (imode, operands[1], mode, 0),
6997 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6998 GET_MODE_SIZE (imode)),
6999 simplify_gen_subreg (imode, operands[1], mode,
7000 GET_MODE_SIZE (imode)),
7005 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7006 cfun->machine->sdmode_stack_slot =
7007 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7009 if (reload_in_progress
7011 && MEM_P (operands[0])
7012 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7013 && REG_P (operands[1]))
7015 if (FP_REGNO_P (REGNO (operands[1])))
7017 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7018 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7019 emit_insn (gen_movsd_store (mem, operands[1]));
7021 else if (INT_REGNO_P (REGNO (operands[1])))
7023 rtx mem = adjust_address_nv (operands[0], mode, 4);
7024 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7025 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7031 if (reload_in_progress
7033 && REG_P (operands[0])
7034 && MEM_P (operands[1])
7035 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7037 if (FP_REGNO_P (REGNO (operands[0])))
7039 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7040 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7041 emit_insn (gen_movsd_load (operands[0], mem));
7043 else if (INT_REGNO_P (REGNO (operands[0])))
7045 rtx mem = adjust_address_nv (operands[1], mode, 4);
7046 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7047 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7054 /* FIXME: In the long term, this switch statement should go away
7055 and be replaced by a sequence of tests based on things like
7061 if (CONSTANT_P (operands[1])
7062 && GET_CODE (operands[1]) != CONST_INT)
7063 operands[1] = force_const_mem (mode, operands[1]);
7068 rs6000_eliminate_indexed_memrefs (operands);
7075 if (CONSTANT_P (operands[1])
7076 && ! easy_fp_constant (operands[1], mode))
7077 operands[1] = force_const_mem (mode, operands[1]);
7090 if (CONSTANT_P (operands[1])
7091 && !easy_vector_constant (operands[1], mode))
7092 operands[1] = force_const_mem (mode, operands[1]);
7097 /* Use default pattern for address of ELF small data */
7100 && DEFAULT_ABI == ABI_V4
7101 && (GET_CODE (operands[1]) == SYMBOL_REF
7102 || GET_CODE (operands[1]) == CONST)
7103 && small_data_operand (operands[1], mode))
7105 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7109 if (DEFAULT_ABI == ABI_V4
7110 && mode == Pmode && mode == SImode
7111 && flag_pic == 1 && got_operand (operands[1], mode))
7113 emit_insn (gen_movsi_got (operands[0], operands[1]));
7117 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7121 && CONSTANT_P (operands[1])
7122 && GET_CODE (operands[1]) != HIGH
7123 && GET_CODE (operands[1]) != CONST_INT)
7125 rtx target = (!can_create_pseudo_p ()
7127 : gen_reg_rtx (mode));
7129 /* If this is a function address on -mcall-aixdesc,
7130 convert it to the address of the descriptor. */
7131 if (DEFAULT_ABI == ABI_AIX
7132 && GET_CODE (operands[1]) == SYMBOL_REF
7133 && XSTR (operands[1], 0)[0] == '.')
7135 const char *name = XSTR (operands[1], 0);
7137 while (*name == '.')
7139 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7140 CONSTANT_POOL_ADDRESS_P (new_ref)
7141 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7142 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7143 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7144 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7145 operands[1] = new_ref;
7148 if (DEFAULT_ABI == ABI_DARWIN)
7151 if (MACHO_DYNAMIC_NO_PIC_P)
7153 /* Take care of any required data indirection. */
7154 operands[1] = rs6000_machopic_legitimize_pic_address (
7155 operands[1], mode, operands[0]);
7156 if (operands[0] != operands[1])
7157 emit_insn (gen_rtx_SET (VOIDmode,
7158 operands[0], operands[1]));
7162 emit_insn (gen_macho_high (target, operands[1]));
7163 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7167 emit_insn (gen_elf_high (target, operands[1]));
7168 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7172 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7173 and we have put it in the TOC, we just need to make a TOC-relative
7176 && GET_CODE (operands[1]) == SYMBOL_REF
7177 && constant_pool_expr_p (operands[1])
7178 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7179 get_pool_mode (operands[1])))
7180 || (TARGET_CMODEL == CMODEL_MEDIUM
7181 && GET_CODE (operands[1]) == SYMBOL_REF
7182 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7183 && SYMBOL_REF_LOCAL_P (operands[1])))
7186 if (TARGET_CMODEL != CMODEL_SMALL)
7188 if (can_create_pseudo_p ())
7189 reg = gen_reg_rtx (Pmode);
7193 operands[1] = create_TOC_reference (operands[1], reg);
7195 else if (mode == Pmode
7196 && CONSTANT_P (operands[1])
7197 && GET_CODE (operands[1]) != HIGH
7198 && !(TARGET_CMODEL != CMODEL_SMALL
7199 && GET_CODE (operands[1]) == CONST
7200 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7201 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7202 && ((GET_CODE (operands[1]) != CONST_INT
7203 && ! easy_fp_constant (operands[1], mode))
7204 || (GET_CODE (operands[1]) == CONST_INT
7205 && (num_insns_constant (operands[1], mode)
7206 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7207 || (GET_CODE (operands[0]) == REG
7208 && FP_REGNO_P (REGNO (operands[0]))))
7209 && ! legitimate_constant_pool_address_p (operands[1], mode,
7211 && ! toc_relative_expr_p (operands[1])
7212 && (TARGET_CMODEL == CMODEL_SMALL
7213 || can_create_pseudo_p ()
7214 || (REG_P (operands[0])
7215 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7219 /* Darwin uses a special PIC legitimizer. */
7220 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7223 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7225 if (operands[0] != operands[1])
7226 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7231 /* If we are to limit the number of things we put in the TOC and
7232 this is a symbol plus a constant we can add in one insn,
7233 just put the symbol in the TOC and add the constant. Don't do
7234 this if reload is in progress. */
7235 if (GET_CODE (operands[1]) == CONST
7236 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7237 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7238 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7239 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7240 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7241 && ! side_effects_p (operands[0]))
7244 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7245 rtx other = XEXP (XEXP (operands[1], 0), 1);
7247 sym = force_reg (mode, sym);
7248 emit_insn (gen_add3_insn (operands[0], sym, other));
7252 operands[1] = force_const_mem (mode, operands[1]);
7255 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7256 && constant_pool_expr_p (XEXP (operands[1], 0))
7257 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7258 get_pool_constant (XEXP (operands[1], 0)),
7259 get_pool_mode (XEXP (operands[1], 0))))
7263 if (TARGET_CMODEL != CMODEL_SMALL)
7265 if (can_create_pseudo_p ())
7266 reg = gen_reg_rtx (Pmode);
7270 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7271 operands[1] = gen_const_mem (mode, tocref);
7272 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7278 rs6000_eliminate_indexed_memrefs (operands);
7282 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7284 gen_rtx_SET (VOIDmode,
7285 operands[0], operands[1]),
7286 gen_rtx_CLOBBER (VOIDmode,
7287 gen_rtx_SCRATCH (SImode)))));
7293 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7296 /* Above, we may have called force_const_mem which may have returned
7297 an invalid address. If we can, fix this up; otherwise, reload will
7298 have to deal with it. */
7299 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7300 operands[1] = validize_mem (operands[1]);
7303 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7306 /* Nonzero if we can use a floating-point register to pass this arg. */
7307 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7308 (SCALAR_FLOAT_MODE_P (MODE) \
7309 && (CUM)->fregno <= FP_ARG_MAX_REG \
7310 && TARGET_HARD_FLOAT && TARGET_FPRS)
7312 /* Nonzero if we can use an AltiVec register to pass this arg. */
7313 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7314 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7315 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7316 && TARGET_ALTIVEC_ABI \
7319 /* Return a nonzero value to say to return the function value in
7320 memory, just as large structures are always returned. TYPE will be
7321 the data type of the value, and FNTYPE will be the type of the
7322 function doing the returning, or @code{NULL} for libcalls.
7324 The AIX ABI for the RS/6000 specifies that all structures are
7325 returned in memory. The Darwin ABI does the same.
7327 For the Darwin 64 Bit ABI, a function result can be returned in
7328 registers or in memory, depending on the size of the return data
7329 type. If it is returned in registers, the value occupies the same
7330 registers as it would if it were the first and only function
7331 argument. Otherwise, the function places its result in memory at
7332 the location pointed to by GPR3.
7334 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7335 but a draft put them in memory, and GCC used to implement the draft
7336 instead of the final standard. Therefore, aix_struct_return
7337 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7338 compatibility can change DRAFT_V4_STRUCT_RET to override the
7339 default, and -m switches get the final word. See
7340 rs6000_option_override_internal for more details.
7342 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7343 long double support is enabled. These values are returned in memory.
7345 int_size_in_bytes returns -1 for variable size objects, which go in
7346 memory always. The cast to unsigned makes -1 > 8. */
7349 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7351 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7353 && rs6000_darwin64_abi
7354 && TREE_CODE (type) == RECORD_TYPE
7355 && int_size_in_bytes (type) > 0)
7357 CUMULATIVE_ARGS valcum;
7361 valcum.fregno = FP_ARG_MIN_REG;
7362 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7363 /* Do a trial code generation as if this were going to be passed
7364 as an argument; if any part goes in memory, we return NULL. */
7365 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7368 /* Otherwise fall through to more conventional ABI rules. */
7371 if (AGGREGATE_TYPE_P (type)
7372 && (aix_struct_return
7373 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7376 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7377 modes only exist for GCC vector types if -maltivec. */
7378 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7379 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7382 /* Return synthetic vectors in memory. */
7383 if (TREE_CODE (type) == VECTOR_TYPE
7384 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7386 static bool warned_for_return_big_vectors = false;
7387 if (!warned_for_return_big_vectors)
7389 warning (0, "GCC vector returned by reference: "
7390 "non-standard ABI extension with no compatibility guarantee");
7391 warned_for_return_big_vectors = true;
7396 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7402 #ifdef HAVE_AS_GNU_ATTRIBUTE
7403 /* Return TRUE if a call to function FNDECL may be one that
7404 potentially affects the function calling ABI of the object file. */
7407 call_ABI_of_interest (tree fndecl)
7409 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7411 struct cgraph_node *c_node;
7413 /* Libcalls are always interesting. */
7414 if (fndecl == NULL_TREE)
7417 /* Any call to an external function is interesting. */
7418 if (DECL_EXTERNAL (fndecl))
7421 /* Interesting functions that we are emitting in this object file. */
7422 c_node = cgraph_get_node (fndecl);
7423 c_node = cgraph_function_or_thunk_node (c_node, NULL);
7424 return !cgraph_only_called_directly_p (c_node);
7430 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7431 for a call to a function whose data type is FNTYPE.
7432 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7434 For incoming args we set the number of arguments in the prototype large
7435 so we never return a PARALLEL. */
7438 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7439 rtx libname ATTRIBUTE_UNUSED, int incoming,
7440 int libcall, int n_named_args,
7441 tree fndecl ATTRIBUTE_UNUSED,
7442 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7444 static CUMULATIVE_ARGS zero_cumulative;
7446 *cum = zero_cumulative;
7448 cum->fregno = FP_ARG_MIN_REG;
7449 cum->vregno = ALTIVEC_ARG_MIN_REG;
7450 cum->prototype = (fntype && prototype_p (fntype));
7451 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7452 ? CALL_LIBCALL : CALL_NORMAL);
7453 cum->sysv_gregno = GP_ARG_MIN_REG;
7454 cum->stdarg = stdarg_p (fntype);
7456 cum->nargs_prototype = 0;
7457 if (incoming || cum->prototype)
7458 cum->nargs_prototype = n_named_args;
7460 /* Check for a longcall attribute. */
7461 if ((!fntype && rs6000_default_long_calls)
7463 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7464 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7465 cum->call_cookie |= CALL_LONG;
7467 if (TARGET_DEBUG_ARG)
7469 fprintf (stderr, "\ninit_cumulative_args:");
7472 tree ret_type = TREE_TYPE (fntype);
7473 fprintf (stderr, " ret code = %s,",
7474 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7477 if (cum->call_cookie & CALL_LONG)
7478 fprintf (stderr, " longcall,");
7480 fprintf (stderr, " proto = %d, nargs = %d\n",
7481 cum->prototype, cum->nargs_prototype);
7484 #ifdef HAVE_AS_GNU_ATTRIBUTE
7485 if (DEFAULT_ABI == ABI_V4)
7487 cum->escapes = call_ABI_of_interest (fndecl);
7494 return_type = TREE_TYPE (fntype);
7495 return_mode = TYPE_MODE (return_type);
7498 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7500 if (return_type != NULL)
7502 if (TREE_CODE (return_type) == RECORD_TYPE
7503 && TYPE_TRANSPARENT_AGGR (return_type))
7505 return_type = TREE_TYPE (first_field (return_type));
7506 return_mode = TYPE_MODE (return_type);
7508 if (AGGREGATE_TYPE_P (return_type)
7509 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7511 rs6000_returns_struct = true;
7513 if (SCALAR_FLOAT_MODE_P (return_mode))
7514 rs6000_passes_float = true;
7515 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7516 || SPE_VECTOR_MODE (return_mode))
7517 rs6000_passes_vector = true;
7524 && TARGET_ALTIVEC_ABI
7525 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7527 error ("cannot return value in vector register because"
7528 " altivec instructions are disabled, use -maltivec"
7533 /* Return true if TYPE must be passed on the stack and not in registers. */
7536 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7538 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7539 return must_pass_in_stack_var_size (mode, type);
7541 return must_pass_in_stack_var_size_or_pad (mode, type);
7544 /* If defined, a C expression which determines whether, and in which
7545 direction, to pad out an argument with extra space. The value
7546 should be of type `enum direction': either `upward' to pad above
7547 the argument, `downward' to pad below, or `none' to inhibit
7550 For the AIX ABI structs are always stored left shifted in their
7554 function_arg_padding (enum machine_mode mode, const_tree type)
7556 #ifndef AGGREGATE_PADDING_FIXED
7557 #define AGGREGATE_PADDING_FIXED 0
7559 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7560 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7563 if (!AGGREGATE_PADDING_FIXED)
7565 /* GCC used to pass structures of the same size as integer types as
7566 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7567 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7568 passed padded downward, except that -mstrict-align further
7569 muddied the water in that multi-component structures of 2 and 4
7570 bytes in size were passed padded upward.
7572 The following arranges for best compatibility with previous
7573 versions of gcc, but removes the -mstrict-align dependency. */
7574 if (BYTES_BIG_ENDIAN)
7576 HOST_WIDE_INT size = 0;
7578 if (mode == BLKmode)
7580 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7581 size = int_size_in_bytes (type);
7584 size = GET_MODE_SIZE (mode);
7586 if (size == 1 || size == 2 || size == 4)
7592 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7594 if (type != 0 && AGGREGATE_TYPE_P (type))
7598 /* Fall back to the default. */
7599 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7602 /* If defined, a C expression that gives the alignment boundary, in bits,
7603 of an argument with the specified mode and type. If it is not defined,
7604 PARM_BOUNDARY is used for all arguments.
7606 V.4 wants long longs and doubles to be double word aligned. Just
7607 testing the mode size is a boneheaded way to do this as it means
7608 that other types such as complex int are also double word aligned.
7609 However, we're stuck with this because changing the ABI might break
7610 existing library interfaces.
7612 Doubleword align SPE vectors.
7613 Quadword align Altivec/VSX vectors.
7614 Quadword align large synthetic vector types. */
7617 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7619 if (DEFAULT_ABI == ABI_V4
7620 && (GET_MODE_SIZE (mode) == 8
7621 || (TARGET_HARD_FLOAT
7623 && (mode == TFmode || mode == TDmode))))
7625 else if (SPE_VECTOR_MODE (mode)
7626 || (type && TREE_CODE (type) == VECTOR_TYPE
7627 && int_size_in_bytes (type) >= 8
7628 && int_size_in_bytes (type) < 16))
7630 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7631 || (type && TREE_CODE (type) == VECTOR_TYPE
7632 && int_size_in_bytes (type) >= 16))
7634 else if (TARGET_MACHO
7635 && rs6000_darwin64_abi
7637 && type && TYPE_ALIGN (type) > 64)
7640 return PARM_BOUNDARY;
7643 /* For a function parm of MODE and TYPE, return the starting word in
7644 the parameter area. NWORDS of the parameter area are already used. */
7647 rs6000_parm_start (enum machine_mode mode, const_tree type,
7648 unsigned int nwords)
7651 unsigned int parm_offset;
7653 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7654 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7655 return nwords + (-(parm_offset + nwords) & align);
7658 /* Compute the size (in words) of a function argument. */
7660 static unsigned long
7661 rs6000_arg_size (enum machine_mode mode, const_tree type)
7665 if (mode != BLKmode)
7666 size = GET_MODE_SIZE (mode);
7668 size = int_size_in_bytes (type);
7671 return (size + 3) >> 2;
7673 return (size + 7) >> 3;
7676 /* Use this to flush pending int fields. */
7679 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7680 HOST_WIDE_INT bitpos, int final)
7682 unsigned int startbit, endbit;
7683 int intregs, intoffset;
7684 enum machine_mode mode;
7686 /* Handle the situations where a float is taking up the first half
7687 of the GPR, and the other half is empty (typically due to
7688 alignment restrictions). We can detect this by a 8-byte-aligned
7689 int field, or by seeing that this is the final flush for this
7690 argument. Count the word and continue on. */
7691 if (cum->floats_in_gpr == 1
7692 && (cum->intoffset % 64 == 0
7693 || (cum->intoffset == -1 && final)))
7696 cum->floats_in_gpr = 0;
7699 if (cum->intoffset == -1)
7702 intoffset = cum->intoffset;
7703 cum->intoffset = -1;
7704 cum->floats_in_gpr = 0;
7706 if (intoffset % BITS_PER_WORD != 0)
7708 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7710 if (mode == BLKmode)
7712 /* We couldn't find an appropriate mode, which happens,
7713 e.g., in packed structs when there are 3 bytes to load.
7714 Back intoffset back to the beginning of the word in this
7716 intoffset = intoffset & -BITS_PER_WORD;
7720 startbit = intoffset & -BITS_PER_WORD;
7721 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7722 intregs = (endbit - startbit) / BITS_PER_WORD;
7723 cum->words += intregs;
7724 /* words should be unsigned. */
7725 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7727 int pad = (endbit/BITS_PER_WORD) - cum->words;
7732 /* The darwin64 ABI calls for us to recurse down through structs,
7733 looking for elements passed in registers. Unfortunately, we have
7734 to track int register count here also because of misalignments
7735 in powerpc alignment mode. */
7738 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7740 HOST_WIDE_INT startbitpos)
7744 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7745 if (TREE_CODE (f) == FIELD_DECL)
7747 HOST_WIDE_INT bitpos = startbitpos;
7748 tree ftype = TREE_TYPE (f);
7749 enum machine_mode mode;
7750 if (ftype == error_mark_node)
7752 mode = TYPE_MODE (ftype);
7754 if (DECL_SIZE (f) != 0
7755 && host_integerp (bit_position (f), 1))
7756 bitpos += int_bit_position (f);
7758 /* ??? FIXME: else assume zero offset. */
7760 if (TREE_CODE (ftype) == RECORD_TYPE)
7761 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7762 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7764 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
7765 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7766 cum->fregno += n_fpregs;
7767 /* Single-precision floats present a special problem for
7768 us, because they are smaller than an 8-byte GPR, and so
7769 the structure-packing rules combined with the standard
7770 varargs behavior mean that we want to pack float/float
7771 and float/int combinations into a single register's
7772 space. This is complicated by the arg advance flushing,
7773 which works on arbitrarily large groups of int-type
7777 if (cum->floats_in_gpr == 1)
7779 /* Two floats in a word; count the word and reset
7782 cum->floats_in_gpr = 0;
7784 else if (bitpos % 64 == 0)
7786 /* A float at the beginning of an 8-byte word;
7787 count it and put off adjusting cum->words until
7788 we see if a arg advance flush is going to do it
7790 cum->floats_in_gpr++;
7794 /* The float is at the end of a word, preceded
7795 by integer fields, so the arg advance flush
7796 just above has already set cum->words and
7797 everything is taken care of. */
7801 cum->words += n_fpregs;
7803 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7805 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7809 else if (cum->intoffset == -1)
7810 cum->intoffset = bitpos;
7814 /* Check for an item that needs to be considered specially under the darwin 64
7815 bit ABI. These are record types where the mode is BLK or the structure is
7818 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7820 return rs6000_darwin64_abi
7821 && ((mode == BLKmode
7822 && TREE_CODE (type) == RECORD_TYPE
7823 && int_size_in_bytes (type) > 0)
7824 || (type && TREE_CODE (type) == RECORD_TYPE
7825 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7828 /* Update the data in CUM to advance over an argument
7829 of mode MODE and data type TYPE.
7830 (TYPE is null for libcalls where that information may not be available.)
7832 Note that for args passed by reference, function_arg will be called
7833 with MODE and TYPE set to that of the pointer to the arg, not the arg
7837 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7838 const_tree type, bool named, int depth)
7840 /* Only tick off an argument if we're not recursing. */
7842 cum->nargs_prototype--;
7844 #ifdef HAVE_AS_GNU_ATTRIBUTE
7845 if (DEFAULT_ABI == ABI_V4
7848 if (SCALAR_FLOAT_MODE_P (mode))
7849 rs6000_passes_float = true;
7850 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
7851 rs6000_passes_vector = true;
7852 else if (SPE_VECTOR_MODE (mode)
7854 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7855 rs6000_passes_vector = true;
7859 if (TARGET_ALTIVEC_ABI
7860 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7861 || (type && TREE_CODE (type) == VECTOR_TYPE
7862 && int_size_in_bytes (type) == 16)))
7866 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7869 if (!TARGET_ALTIVEC)
7870 error ("cannot pass argument in vector register because"
7871 " altivec instructions are disabled, use -maltivec"
7874 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7875 even if it is going to be passed in a vector register.
7876 Darwin does the same for variable-argument functions. */
7877 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7878 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7888 /* Vector parameters must be 16-byte aligned. This places
7889 them at 2 mod 4 in terms of words in 32-bit mode, since
7890 the parameter save area starts at offset 24 from the
7891 stack. In 64-bit mode, they just have to start on an
7892 even word, since the parameter save area is 16-byte
7893 aligned. Space for GPRs is reserved even if the argument
7894 will be passed in memory. */
7896 align = (2 - cum->words) & 3;
7898 align = cum->words & 1;
7899 cum->words += align + rs6000_arg_size (mode, type);
7901 if (TARGET_DEBUG_ARG)
7903 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7905 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7906 cum->nargs_prototype, cum->prototype,
7907 GET_MODE_NAME (mode));
7911 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7913 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7916 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7918 int size = int_size_in_bytes (type);
7919 /* Variable sized types have size == -1 and are
7920 treated as if consisting entirely of ints.
7921 Pad to 16 byte boundary if needed. */
7922 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7923 && (cum->words % 2) != 0)
7925 /* For varargs, we can just go up by the size of the struct. */
7927 cum->words += (size + 7) / 8;
7930 /* It is tempting to say int register count just goes up by
7931 sizeof(type)/8, but this is wrong in a case such as
7932 { int; double; int; } [powerpc alignment]. We have to
7933 grovel through the fields for these too. */
7935 cum->floats_in_gpr = 0;
7936 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7937 rs6000_darwin64_record_arg_advance_flush (cum,
7938 size * BITS_PER_UNIT, 1);
7940 if (TARGET_DEBUG_ARG)
7942 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7943 cum->words, TYPE_ALIGN (type), size);
7945 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7946 cum->nargs_prototype, cum->prototype,
7947 GET_MODE_NAME (mode));
7950 else if (DEFAULT_ABI == ABI_V4)
7952 if (TARGET_HARD_FLOAT && TARGET_FPRS
7953 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7954 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7955 || (mode == TFmode && !TARGET_IEEEQUAD)
7956 || mode == SDmode || mode == DDmode || mode == TDmode))
7958 /* _Decimal128 must use an even/odd register pair. This assumes
7959 that the register number is odd when fregno is odd. */
7960 if (mode == TDmode && (cum->fregno % 2) == 1)
7963 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7964 <= FP_ARG_V4_MAX_REG)
7965 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7968 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7969 if (mode == DFmode || mode == TFmode
7970 || mode == DDmode || mode == TDmode)
7971 cum->words += cum->words & 1;
7972 cum->words += rs6000_arg_size (mode, type);
7977 int n_words = rs6000_arg_size (mode, type);
7978 int gregno = cum->sysv_gregno;
7980 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7981 (r7,r8) or (r9,r10). As does any other 2 word item such
7982 as complex int due to a historical mistake. */
7984 gregno += (1 - gregno) & 1;
7986 /* Multi-reg args are not split between registers and stack. */
7987 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7989 /* Long long and SPE vectors are aligned on the stack.
7990 So are other 2 word items such as complex int due to
7991 a historical mistake. */
7993 cum->words += cum->words & 1;
7994 cum->words += n_words;
7997 /* Note: continuing to accumulate gregno past when we've started
7998 spilling to the stack indicates the fact that we've started
7999 spilling to the stack to expand_builtin_saveregs. */
8000 cum->sysv_gregno = gregno + n_words;
8003 if (TARGET_DEBUG_ARG)
8005 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8006 cum->words, cum->fregno);
8007 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8008 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8009 fprintf (stderr, "mode = %4s, named = %d\n",
8010 GET_MODE_NAME (mode), named);
8015 int n_words = rs6000_arg_size (mode, type);
8016 int start_words = cum->words;
8017 int align_words = rs6000_parm_start (mode, type, start_words);
8019 cum->words = align_words + n_words;
8021 if (SCALAR_FLOAT_MODE_P (mode)
8022 && TARGET_HARD_FLOAT && TARGET_FPRS)
8024 /* _Decimal128 must be passed in an even/odd float register pair.
8025 This assumes that the register number is odd when fregno is
8027 if (mode == TDmode && (cum->fregno % 2) == 1)
8029 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8032 if (TARGET_DEBUG_ARG)
8034 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8035 cum->words, cum->fregno);
8036 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8037 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8038 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8039 named, align_words - start_words, depth);
8045 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
8046 const_tree type, bool named)
8048 rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
8053 spe_build_register_parallel (enum machine_mode mode, int gregno)
8060 r1 = gen_rtx_REG (DImode, gregno);
8061 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8062 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8066 r1 = gen_rtx_REG (DImode, gregno);
8067 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8068 r3 = gen_rtx_REG (DImode, gregno + 2);
8069 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8070 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8073 r1 = gen_rtx_REG (DImode, gregno);
8074 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8075 r3 = gen_rtx_REG (DImode, gregno + 2);
8076 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8077 r5 = gen_rtx_REG (DImode, gregno + 4);
8078 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8079 r7 = gen_rtx_REG (DImode, gregno + 6);
8080 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8081 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8088 /* Determine where to put a SIMD argument on the SPE. */
8090 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8093 int gregno = cum->sysv_gregno;
8095 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8096 are passed and returned in a pair of GPRs for ABI compatibility. */
8097 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8098 || mode == DCmode || mode == TCmode))
8100 int n_words = rs6000_arg_size (mode, type);
8102 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8104 gregno += (1 - gregno) & 1;
8106 /* Multi-reg args are not split between registers and stack. */
8107 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8110 return spe_build_register_parallel (mode, gregno);
8114 int n_words = rs6000_arg_size (mode, type);
8116 /* SPE vectors are put in odd registers. */
8117 if (n_words == 2 && (gregno & 1) == 0)
8120 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8123 enum machine_mode m = SImode;
8125 r1 = gen_rtx_REG (m, gregno);
8126 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8127 r2 = gen_rtx_REG (m, gregno + 1);
8128 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8129 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8136 if (gregno <= GP_ARG_MAX_REG)
8137 return gen_rtx_REG (mode, gregno);
8143 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8144 structure between cum->intoffset and bitpos to integer registers. */
8147 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8148 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8150 enum machine_mode mode;
8152 unsigned int startbit, endbit;
8153 int this_regno, intregs, intoffset;
8156 if (cum->intoffset == -1)
8159 intoffset = cum->intoffset;
8160 cum->intoffset = -1;
8162 /* If this is the trailing part of a word, try to only load that
8163 much into the register. Otherwise load the whole register. Note
8164 that in the latter case we may pick up unwanted bits. It's not a
8165 problem at the moment but may wish to revisit. */
8167 if (intoffset % BITS_PER_WORD != 0)
8169 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8171 if (mode == BLKmode)
8173 /* We couldn't find an appropriate mode, which happens,
8174 e.g., in packed structs when there are 3 bytes to load.
8175 Back intoffset back to the beginning of the word in this
8177 intoffset = intoffset & -BITS_PER_WORD;
8184 startbit = intoffset & -BITS_PER_WORD;
8185 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8186 intregs = (endbit - startbit) / BITS_PER_WORD;
8187 this_regno = cum->words + intoffset / BITS_PER_WORD;
8189 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8192 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8196 intoffset /= BITS_PER_UNIT;
8199 regno = GP_ARG_MIN_REG + this_regno;
8200 reg = gen_rtx_REG (mode, regno);
8202 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8205 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8209 while (intregs > 0);
8212 /* Recursive workhorse for the following. */
8215 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8216 HOST_WIDE_INT startbitpos, rtx rvec[],
8221 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8222 if (TREE_CODE (f) == FIELD_DECL)
8224 HOST_WIDE_INT bitpos = startbitpos;
8225 tree ftype = TREE_TYPE (f);
8226 enum machine_mode mode;
8227 if (ftype == error_mark_node)
8229 mode = TYPE_MODE (ftype);
8231 if (DECL_SIZE (f) != 0
8232 && host_integerp (bit_position (f), 1))
8233 bitpos += int_bit_position (f);
8235 /* ??? FIXME: else assume zero offset. */
8237 if (TREE_CODE (ftype) == RECORD_TYPE)
8238 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8239 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8241 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8245 case SCmode: mode = SFmode; break;
8246 case DCmode: mode = DFmode; break;
8247 case TCmode: mode = TFmode; break;
8251 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8252 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8254 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8255 && (mode == TFmode || mode == TDmode));
8256 /* Long double or _Decimal128 split over regs and memory. */
8257 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8261 = gen_rtx_EXPR_LIST (VOIDmode,
8262 gen_rtx_REG (mode, cum->fregno++),
8263 GEN_INT (bitpos / BITS_PER_UNIT));
8264 if (mode == TFmode || mode == TDmode)
8267 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8269 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8271 = gen_rtx_EXPR_LIST (VOIDmode,
8272 gen_rtx_REG (mode, cum->vregno++),
8273 GEN_INT (bitpos / BITS_PER_UNIT));
8275 else if (cum->intoffset == -1)
8276 cum->intoffset = bitpos;
8280 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8281 the register(s) to be used for each field and subfield of a struct
8282 being passed by value, along with the offset of where the
8283 register's value may be found in the block. FP fields go in FP
8284 register, vector fields go in vector registers, and everything
8285 else goes in int registers, packed as in memory.
8287 This code is also used for function return values. RETVAL indicates
8288 whether this is the case.
8290 Much of this is taken from the SPARC V9 port, which has a similar
8291 calling convention. */
8294 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8295 bool named, bool retval)
8297 rtx rvec[FIRST_PSEUDO_REGISTER];
8298 int k = 1, kbase = 1;
8299 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8300 /* This is a copy; modifications are not visible to our caller. */
8301 CUMULATIVE_ARGS copy_cum = *orig_cum;
8302 CUMULATIVE_ARGS *cum = ©_cum;
8304 /* Pad to 16 byte boundary if needed. */
8305 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8306 && (cum->words % 2) != 0)
8313 /* Put entries into rvec[] for individual FP and vector fields, and
8314 for the chunks of memory that go in int regs. Note we start at
8315 element 1; 0 is reserved for an indication of using memory, and
8316 may or may not be filled in below. */
8317 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8318 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8320 /* If any part of the struct went on the stack put all of it there.
8321 This hack is because the generic code for
8322 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8323 parts of the struct are not at the beginning. */
8327 return NULL_RTX; /* doesn't go in registers at all */
8329 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8331 if (k > 1 || cum->use_stack)
8332 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8337 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8340 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8345 rtx rvec[GP_ARG_NUM_REG + 1];
8347 if (align_words >= GP_ARG_NUM_REG)
8350 n_units = rs6000_arg_size (mode, type);
8352 /* Optimize the simple case where the arg fits in one gpr, except in
8353 the case of BLKmode due to assign_parms assuming that registers are
8354 BITS_PER_WORD wide. */
8356 || (n_units == 1 && mode != BLKmode))
8357 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8360 if (align_words + n_units > GP_ARG_NUM_REG)
8361 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8362 using a magic NULL_RTX component.
8363 This is not strictly correct. Only some of the arg belongs in
8364 memory, not all of it. However, the normal scheme using
8365 function_arg_partial_nregs can result in unusual subregs, eg.
8366 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8367 store the whole arg to memory is often more efficient than code
8368 to store pieces, and we know that space is available in the right
8369 place for the whole arg. */
8370 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8375 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8376 rtx off = GEN_INT (i++ * 4);
8377 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8379 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8381 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8384 /* Determine where to put an argument to a function.
8385 Value is zero to push the argument on the stack,
8386 or a hard register in which to store the argument.
8388 MODE is the argument's machine mode.
8389 TYPE is the data type of the argument (as a tree).
8390 This is null for libcalls where that information may
8392 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8393 the preceding args and about the function being called. It is
8394 not modified in this routine.
8395 NAMED is nonzero if this argument is a named parameter
8396 (otherwise it is an extra parameter matching an ellipsis).
8398 On RS/6000 the first eight words of non-FP are normally in registers
8399 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8400 Under V.4, the first 8 FP args are in registers.
8402 If this is floating-point and no prototype is specified, we use
8403 both an FP and integer register (or possibly FP reg and stack). Library
8404 functions (when CALL_LIBCALL is set) always have the proper types for args,
8405 so we can pass the FP value just in one register. emit_library_function
8406 doesn't support PARALLEL anyway.
8408 Note that for args passed by reference, function_arg will be called
8409 with MODE and TYPE set to that of the pointer to the arg, not the arg
8413 rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
8414 const_tree type, bool named)
8416 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8417 enum rs6000_abi abi = DEFAULT_ABI;
8419 /* Return a marker to indicate whether CR1 needs to set or clear the
8420 bit that V.4 uses to say fp args were passed in registers.
8421 Assume that we don't need the marker for software floating point,
8422 or compiler generated library calls. */
8423 if (mode == VOIDmode)
8426 && (cum->call_cookie & CALL_LIBCALL) == 0
8428 || (cum->nargs_prototype < 0
8429 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8431 /* For the SPE, we need to crxor CR6 always. */
8433 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8434 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8435 return GEN_INT (cum->call_cookie
8436 | ((cum->fregno == FP_ARG_MIN_REG)
8437 ? CALL_V4_SET_FP_ARGS
8438 : CALL_V4_CLEAR_FP_ARGS));
8441 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8444 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8446 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8447 if (rslt != NULL_RTX)
8449 /* Else fall through to usual handling. */
8452 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8453 if (TARGET_64BIT && ! cum->prototype)
8455 /* Vector parameters get passed in vector register
8456 and also in GPRs or memory, in absence of prototype. */
8459 align_words = (cum->words + 1) & ~1;
8461 if (align_words >= GP_ARG_NUM_REG)
8467 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8469 return gen_rtx_PARALLEL (mode,
8471 gen_rtx_EXPR_LIST (VOIDmode,
8473 gen_rtx_EXPR_LIST (VOIDmode,
8474 gen_rtx_REG (mode, cum->vregno),
8478 return gen_rtx_REG (mode, cum->vregno);
8479 else if (TARGET_ALTIVEC_ABI
8480 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8481 || (type && TREE_CODE (type) == VECTOR_TYPE
8482 && int_size_in_bytes (type) == 16)))
8484 if (named || abi == ABI_V4)
8488 /* Vector parameters to varargs functions under AIX or Darwin
8489 get passed in memory and possibly also in GPRs. */
8490 int align, align_words, n_words;
8491 enum machine_mode part_mode;
8493 /* Vector parameters must be 16-byte aligned. This places them at
8494 2 mod 4 in terms of words in 32-bit mode, since the parameter
8495 save area starts at offset 24 from the stack. In 64-bit mode,
8496 they just have to start on an even word, since the parameter
8497 save area is 16-byte aligned. */
8499 align = (2 - cum->words) & 3;
8501 align = cum->words & 1;
8502 align_words = cum->words + align;
8504 /* Out of registers? Memory, then. */
8505 if (align_words >= GP_ARG_NUM_REG)
8508 if (TARGET_32BIT && TARGET_POWERPC64)
8509 return rs6000_mixed_function_arg (mode, type, align_words);
8511 /* The vector value goes in GPRs. Only the part of the
8512 value in GPRs is reported here. */
8514 n_words = rs6000_arg_size (mode, type);
8515 if (align_words + n_words > GP_ARG_NUM_REG)
8516 /* Fortunately, there are only two possibilities, the value
8517 is either wholly in GPRs or half in GPRs and half not. */
8520 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8523 else if (TARGET_SPE_ABI && TARGET_SPE
8524 && (SPE_VECTOR_MODE (mode)
8525 || (TARGET_E500_DOUBLE && (mode == DFmode
8528 || mode == TCmode))))
8529 return rs6000_spe_function_arg (cum, mode, type);
8531 else if (abi == ABI_V4)
8533 if (TARGET_HARD_FLOAT && TARGET_FPRS
8534 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8535 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8536 || (mode == TFmode && !TARGET_IEEEQUAD)
8537 || mode == SDmode || mode == DDmode || mode == TDmode))
8539 /* _Decimal128 must use an even/odd register pair. This assumes
8540 that the register number is odd when fregno is odd. */
8541 if (mode == TDmode && (cum->fregno % 2) == 1)
8544 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8545 <= FP_ARG_V4_MAX_REG)
8546 return gen_rtx_REG (mode, cum->fregno);
8552 int n_words = rs6000_arg_size (mode, type);
8553 int gregno = cum->sysv_gregno;
8555 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8556 (r7,r8) or (r9,r10). As does any other 2 word item such
8557 as complex int due to a historical mistake. */
8559 gregno += (1 - gregno) & 1;
8561 /* Multi-reg args are not split between registers and stack. */
8562 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8565 if (TARGET_32BIT && TARGET_POWERPC64)
8566 return rs6000_mixed_function_arg (mode, type,
8567 gregno - GP_ARG_MIN_REG);
8568 return gen_rtx_REG (mode, gregno);
8573 int align_words = rs6000_parm_start (mode, type, cum->words);
8575 /* _Decimal128 must be passed in an even/odd float register pair.
8576 This assumes that the register number is odd when fregno is odd. */
8577 if (mode == TDmode && (cum->fregno % 2) == 1)
8580 if (USE_FP_FOR_ARG_P (cum, mode, type))
8582 rtx rvec[GP_ARG_NUM_REG + 1];
8586 enum machine_mode fmode = mode;
8587 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8589 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8591 /* Currently, we only ever need one reg here because complex
8592 doubles are split. */
8593 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8594 && (fmode == TFmode || fmode == TDmode));
8596 /* Long double or _Decimal128 split over regs and memory. */
8597 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8600 /* Do we also need to pass this arg in the parameter save
8603 && (cum->nargs_prototype <= 0
8604 || (DEFAULT_ABI == ABI_AIX
8606 && align_words >= GP_ARG_NUM_REG)));
8608 if (!needs_psave && mode == fmode)
8609 return gen_rtx_REG (fmode, cum->fregno);
8614 /* Describe the part that goes in gprs or the stack.
8615 This piece must come first, before the fprs. */
8616 if (align_words < GP_ARG_NUM_REG)
8618 unsigned long n_words = rs6000_arg_size (mode, type);
8620 if (align_words + n_words > GP_ARG_NUM_REG
8621 || (TARGET_32BIT && TARGET_POWERPC64))
8623 /* If this is partially on the stack, then we only
8624 include the portion actually in registers here. */
8625 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8628 if (align_words + n_words > GP_ARG_NUM_REG)
8629 /* Not all of the arg fits in gprs. Say that it
8630 goes in memory too, using a magic NULL_RTX
8631 component. Also see comment in
8632 rs6000_mixed_function_arg for why the normal
8633 function_arg_partial_nregs scheme doesn't work
8635 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8639 r = gen_rtx_REG (rmode,
8640 GP_ARG_MIN_REG + align_words);
8641 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8642 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8644 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8648 /* The whole arg fits in gprs. */
8649 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8650 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8654 /* It's entirely in memory. */
8655 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8658 /* Describe where this piece goes in the fprs. */
8659 r = gen_rtx_REG (fmode, cum->fregno);
8660 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8662 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8664 else if (align_words < GP_ARG_NUM_REG)
8666 if (TARGET_32BIT && TARGET_POWERPC64)
8667 return rs6000_mixed_function_arg (mode, type, align_words);
8669 if (mode == BLKmode)
8672 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8679 /* For an arg passed partly in registers and partly in memory, this is
8680 the number of bytes passed in registers. For args passed entirely in
8681 registers or entirely in memory, zero. When an arg is described by a
8682 PARALLEL, perhaps using more than one register type, this function
8683 returns the number of bytes used by the first element of the PARALLEL. */
8686 rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
8687 tree type, bool named)
8689 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8693 if (DEFAULT_ABI == ABI_V4)
8696 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8697 && cum->nargs_prototype >= 0)
8700 /* In this complicated case we just disable the partial_nregs code. */
8701 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8704 align_words = rs6000_parm_start (mode, type, cum->words);
8706 if (USE_FP_FOR_ARG_P (cum, mode, type))
8708 /* If we are passing this arg in the fixed parameter save area
8709 (gprs or memory) as well as fprs, then this function should
8710 return the number of partial bytes passed in the parameter
8711 save area rather than partial bytes passed in fprs. */
8713 && (cum->nargs_prototype <= 0
8714 || (DEFAULT_ABI == ABI_AIX
8716 && align_words >= GP_ARG_NUM_REG)))
8718 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8719 > FP_ARG_MAX_REG + 1)
8720 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8721 else if (cum->nargs_prototype >= 0)
8725 if (align_words < GP_ARG_NUM_REG
8726 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8727 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8729 if (ret != 0 && TARGET_DEBUG_ARG)
8730 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8735 /* A C expression that indicates when an argument must be passed by
8736 reference. If nonzero for an argument, a copy of that argument is
8737 made in memory and a pointer to the argument is passed instead of
8738 the argument itself. The pointer is passed in whatever way is
8739 appropriate for passing a pointer to that type.
8741 Under V.4, aggregates and long double are passed by reference.
8743 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8744 reference unless the AltiVec vector extension ABI is in force.
8746 As an extension to all ABIs, variable sized types are passed by
8750 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
8751 enum machine_mode mode, const_tree type,
8752 bool named ATTRIBUTE_UNUSED)
8754 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8756 if (TARGET_DEBUG_ARG)
8757 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8764 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8766 if (TARGET_DEBUG_ARG)
8767 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8771 if (int_size_in_bytes (type) < 0)
8773 if (TARGET_DEBUG_ARG)
8774 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8778 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8779 modes only exist for GCC vector types if -maltivec. */
8780 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8782 if (TARGET_DEBUG_ARG)
8783 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8787 /* Pass synthetic vectors in memory. */
8788 if (TREE_CODE (type) == VECTOR_TYPE
8789 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8791 static bool warned_for_pass_big_vectors = false;
8792 if (TARGET_DEBUG_ARG)
8793 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8794 if (!warned_for_pass_big_vectors)
8796 warning (0, "GCC vector passed by reference: "
8797 "non-standard ABI extension with no compatibility guarantee");
8798 warned_for_pass_big_vectors = true;
8807 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8810 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8815 for (i = 0; i < nregs; i++)
8817 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8818 if (reload_completed)
8820 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8823 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8824 i * GET_MODE_SIZE (reg_mode));
8827 tem = replace_equiv_address (tem, XEXP (tem, 0));
8831 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8835 /* Perform any needed actions needed for a function that is receiving a
8836 variable number of arguments.
8840 MODE and TYPE are the mode and type of the current parameter.
8842 PRETEND_SIZE is a variable that should be set to the amount of stack
8843 that must be pushed by the prolog to pretend that our caller pushed
8846 Normally, this macro will push all remaining incoming registers on the
8847 stack and set PRETEND_SIZE to the length of the registers pushed. */
8850 setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
8851 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8854 CUMULATIVE_ARGS next_cum;
8855 int reg_size = TARGET_32BIT ? 4 : 8;
8856 rtx save_area = NULL_RTX, mem;
8857 int first_reg_offset;
8860 /* Skip the last named argument. */
8861 next_cum = *get_cumulative_args (cum);
8862 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8864 if (DEFAULT_ABI == ABI_V4)
8866 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8870 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8871 HOST_WIDE_INT offset = 0;
8873 /* Try to optimize the size of the varargs save area.
8874 The ABI requires that ap.reg_save_area is doubleword
8875 aligned, but we don't need to allocate space for all
8876 the bytes, only those to which we actually will save
8878 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8879 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8880 if (TARGET_HARD_FLOAT && TARGET_FPRS
8881 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8882 && cfun->va_list_fpr_size)
8885 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8886 * UNITS_PER_FP_WORD;
8887 if (cfun->va_list_fpr_size
8888 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8889 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8891 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8892 * UNITS_PER_FP_WORD;
8896 offset = -((first_reg_offset * reg_size) & ~7);
8897 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8899 gpr_reg_num = cfun->va_list_gpr_size;
8900 if (reg_size == 4 && (first_reg_offset & 1))
8903 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8906 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8908 - (int) (GP_ARG_NUM_REG * reg_size);
8910 if (gpr_size + fpr_size)
8913 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8914 gcc_assert (GET_CODE (reg_save_area) == MEM);
8915 reg_save_area = XEXP (reg_save_area, 0);
8916 if (GET_CODE (reg_save_area) == PLUS)
8918 gcc_assert (XEXP (reg_save_area, 0)
8919 == virtual_stack_vars_rtx);
8920 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8921 offset += INTVAL (XEXP (reg_save_area, 1));
8924 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8927 cfun->machine->varargs_save_offset = offset;
8928 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8933 first_reg_offset = next_cum.words;
8934 save_area = virtual_incoming_args_rtx;
8936 if (targetm.calls.must_pass_in_stack (mode, type))
8937 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8940 set = get_varargs_alias_set ();
8941 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8942 && cfun->va_list_gpr_size)
8944 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8946 if (va_list_gpr_counter_field)
8948 /* V4 va_list_gpr_size counts number of registers needed. */
8949 if (nregs > cfun->va_list_gpr_size)
8950 nregs = cfun->va_list_gpr_size;
8954 /* char * va_list instead counts number of bytes needed. */
8955 if (nregs > cfun->va_list_gpr_size / reg_size)
8956 nregs = cfun->va_list_gpr_size / reg_size;
8959 mem = gen_rtx_MEM (BLKmode,
8960 plus_constant (save_area,
8961 first_reg_offset * reg_size));
8962 MEM_NOTRAP_P (mem) = 1;
8963 set_mem_alias_set (mem, set);
8964 set_mem_align (mem, BITS_PER_WORD);
8966 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8970 /* Save FP registers if needed. */
8971 if (DEFAULT_ABI == ABI_V4
8972 && TARGET_HARD_FLOAT && TARGET_FPRS
8974 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8975 && cfun->va_list_fpr_size)
8977 int fregno = next_cum.fregno, nregs;
8978 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8979 rtx lab = gen_label_rtx ();
8980 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8981 * UNITS_PER_FP_WORD);
8984 (gen_rtx_SET (VOIDmode,
8986 gen_rtx_IF_THEN_ELSE (VOIDmode,
8987 gen_rtx_NE (VOIDmode, cr1,
8989 gen_rtx_LABEL_REF (VOIDmode, lab),
8993 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8994 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8996 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8998 plus_constant (save_area, off));
8999 MEM_NOTRAP_P (mem) = 1;
9000 set_mem_alias_set (mem, set);
9001 set_mem_align (mem, GET_MODE_ALIGNMENT (
9002 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9003 ? DFmode : SFmode));
9004 emit_move_insn (mem, gen_rtx_REG (
9005 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9006 ? DFmode : SFmode, fregno));
9013 /* Create the va_list data type. */
9016 rs6000_build_builtin_va_list (void)
9018 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9020 /* For AIX, prefer 'char *' because that's what the system
9021 header files like. */
9022 if (DEFAULT_ABI != ABI_V4)
9023 return build_pointer_type (char_type_node);
9025 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9026 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9027 get_identifier ("__va_list_tag"), record);
9029 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9030 unsigned_char_type_node);
9031 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9032 unsigned_char_type_node);
9033 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9035 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9036 get_identifier ("reserved"), short_unsigned_type_node);
9037 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9038 get_identifier ("overflow_arg_area"),
9040 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9041 get_identifier ("reg_save_area"),
9044 va_list_gpr_counter_field = f_gpr;
9045 va_list_fpr_counter_field = f_fpr;
9047 DECL_FIELD_CONTEXT (f_gpr) = record;
9048 DECL_FIELD_CONTEXT (f_fpr) = record;
9049 DECL_FIELD_CONTEXT (f_res) = record;
9050 DECL_FIELD_CONTEXT (f_ovf) = record;
9051 DECL_FIELD_CONTEXT (f_sav) = record;
9053 TYPE_STUB_DECL (record) = type_decl;
9054 TYPE_NAME (record) = type_decl;
9055 TYPE_FIELDS (record) = f_gpr;
9056 DECL_CHAIN (f_gpr) = f_fpr;
9057 DECL_CHAIN (f_fpr) = f_res;
9058 DECL_CHAIN (f_res) = f_ovf;
9059 DECL_CHAIN (f_ovf) = f_sav;
9061 layout_type (record);
9063 /* The correct type is an array type of one element. */
9064 return build_array_type (record, build_index_type (size_zero_node));
9067 /* Implement va_start. */
9070 rs6000_va_start (tree valist, rtx nextarg)
9072 HOST_WIDE_INT words, n_gpr, n_fpr;
9073 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9074 tree gpr, fpr, ovf, sav, t;
9076 /* Only SVR4 needs something special. */
9077 if (DEFAULT_ABI != ABI_V4)
9079 std_expand_builtin_va_start (valist, nextarg);
9083 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9084 f_fpr = DECL_CHAIN (f_gpr);
9085 f_res = DECL_CHAIN (f_fpr);
9086 f_ovf = DECL_CHAIN (f_res);
9087 f_sav = DECL_CHAIN (f_ovf);
9089 valist = build_simple_mem_ref (valist);
9090 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9091 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9093 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9095 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9098 /* Count number of gp and fp argument registers used. */
9099 words = crtl->args.info.words;
9100 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9102 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9105 if (TARGET_DEBUG_ARG)
9106 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9107 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9108 words, n_gpr, n_fpr);
9110 if (cfun->va_list_gpr_size)
9112 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9113 build_int_cst (NULL_TREE, n_gpr));
9114 TREE_SIDE_EFFECTS (t) = 1;
9115 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9118 if (cfun->va_list_fpr_size)
9120 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9121 build_int_cst (NULL_TREE, n_fpr));
9122 TREE_SIDE_EFFECTS (t) = 1;
9123 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9125 #ifdef HAVE_AS_GNU_ATTRIBUTE
9126 if (call_ABI_of_interest (cfun->decl))
9127 rs6000_passes_float = true;
9131 /* Find the overflow area. */
9132 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9134 t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
9135 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9136 TREE_SIDE_EFFECTS (t) = 1;
9137 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9139 /* If there were no va_arg invocations, don't set up the register
9141 if (!cfun->va_list_gpr_size
9142 && !cfun->va_list_fpr_size
9143 && n_gpr < GP_ARG_NUM_REG
9144 && n_fpr < FP_ARG_V4_MAX_REG)
9147 /* Find the register save area. */
9148 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9149 if (cfun->machine->varargs_save_offset)
9150 t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
9151 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9152 TREE_SIDE_EFFECTS (t) = 1;
9153 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9156 /* Implement va_arg. */
9159 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9162 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9163 tree gpr, fpr, ovf, sav, reg, t, u;
9164 int size, rsize, n_reg, sav_ofs, sav_scale;
9165 tree lab_false, lab_over, addr;
9167 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9171 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9173 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9174 return build_va_arg_indirect_ref (t);
9177 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9178 earlier version of gcc, with the property that it always applied alignment
9179 adjustments to the va-args (even for zero-sized types). The cheapest way
9180 to deal with this is to replicate the effect of the part of
9181 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9183 We don't need to check for pass-by-reference because of the test above.
9184 We can return a simplifed answer, since we know there's no offset to add. */
9187 && rs6000_darwin64_abi
9188 && integer_zerop (TYPE_SIZE (type)))
9190 unsigned HOST_WIDE_INT align, boundary;
9191 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9192 align = PARM_BOUNDARY / BITS_PER_UNIT;
9193 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9194 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9195 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9196 boundary /= BITS_PER_UNIT;
9197 if (boundary > align)
9200 /* This updates arg ptr by the amount that would be necessary
9201 to align the zero-sized (but not zero-alignment) item. */
9202 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9203 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
9204 gimplify_and_add (t, pre_p);
9206 t = fold_convert (sizetype, valist_tmp);
9207 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9208 fold_convert (TREE_TYPE (valist),
9209 fold_build2 (BIT_AND_EXPR, sizetype, t,
9210 size_int (-boundary))));
9211 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9212 gimplify_and_add (t, pre_p);
9214 /* Since it is zero-sized there's no increment for the item itself. */
9215 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9216 return build_va_arg_indirect_ref (valist_tmp);
9219 if (DEFAULT_ABI != ABI_V4)
9221 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9223 tree elem_type = TREE_TYPE (type);
9224 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9225 int elem_size = GET_MODE_SIZE (elem_mode);
9227 if (elem_size < UNITS_PER_WORD)
9229 tree real_part, imag_part;
9230 gimple_seq post = NULL;
9232 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9234 /* Copy the value into a temporary, lest the formal temporary
9235 be reused out from under us. */
9236 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9237 gimple_seq_add_seq (pre_p, post);
9239 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9242 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9246 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9249 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9250 f_fpr = DECL_CHAIN (f_gpr);
9251 f_res = DECL_CHAIN (f_fpr);
9252 f_ovf = DECL_CHAIN (f_res);
9253 f_sav = DECL_CHAIN (f_ovf);
9255 valist = build_va_arg_indirect_ref (valist);
9256 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9257 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9259 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9261 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9264 size = int_size_in_bytes (type);
9265 rsize = (size + 3) / 4;
9268 if (TARGET_HARD_FLOAT && TARGET_FPRS
9269 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9270 || (TARGET_DOUBLE_FLOAT
9271 && (TYPE_MODE (type) == DFmode
9272 || TYPE_MODE (type) == TFmode
9273 || TYPE_MODE (type) == SDmode
9274 || TYPE_MODE (type) == DDmode
9275 || TYPE_MODE (type) == TDmode))))
9277 /* FP args go in FP registers, if present. */
9279 n_reg = (size + 7) / 8;
9280 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9281 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9282 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9287 /* Otherwise into GP registers. */
9296 /* Pull the value out of the saved registers.... */
9299 addr = create_tmp_var (ptr_type_node, "addr");
9301 /* AltiVec vectors never go in registers when -mabi=altivec. */
9302 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9306 lab_false = create_artificial_label (input_location);
9307 lab_over = create_artificial_label (input_location);
9309 /* Long long and SPE vectors are aligned in the registers.
9310 As are any other 2 gpr item such as complex int due to a
9311 historical mistake. */
9313 if (n_reg == 2 && reg == gpr)
9316 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9317 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9318 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9319 unshare_expr (reg), u);
9321 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9322 reg number is 0 for f1, so we want to make it odd. */
9323 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9325 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9326 build_int_cst (TREE_TYPE (reg), 1));
9327 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9330 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9331 t = build2 (GE_EXPR, boolean_type_node, u, t);
9332 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9333 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9334 gimplify_and_add (t, pre_p);
9338 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
9340 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9341 build_int_cst (TREE_TYPE (reg), n_reg));
9342 u = fold_convert (sizetype, u);
9343 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9344 t = fold_build_pointer_plus (t, u);
9346 /* _Decimal32 varargs are located in the second word of the 64-bit
9347 FP register for 32-bit binaries. */
9348 if (!TARGET_POWERPC64
9349 && TARGET_HARD_FLOAT && TARGET_FPRS
9350 && TYPE_MODE (type) == SDmode)
9351 t = fold_build_pointer_plus_hwi (t, size);
9353 gimplify_assign (addr, t, pre_p);
9355 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9357 stmt = gimple_build_label (lab_false);
9358 gimple_seq_add_stmt (pre_p, stmt);
9360 if ((n_reg == 2 && !regalign) || n_reg > 2)
9362 /* Ensure that we don't find any more args in regs.
9363 Alignment has taken care of for special cases. */
9364 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9368 /* ... otherwise out of the overflow area. */
9370 /* Care for on-stack alignment if needed. */
9374 t = fold_build_pointer_plus_hwi (t, align - 1);
9375 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9376 build_int_cst (TREE_TYPE (t), -align));
9378 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9380 gimplify_assign (unshare_expr (addr), t, pre_p);
9382 t = fold_build_pointer_plus_hwi (t, size);
9383 gimplify_assign (unshare_expr (ovf), t, pre_p);
9387 stmt = gimple_build_label (lab_over);
9388 gimple_seq_add_stmt (pre_p, stmt);
9391 if (STRICT_ALIGNMENT
9392 && (TYPE_ALIGN (type)
9393 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9395 /* The value (of type complex double, for example) may not be
9396 aligned in memory in the saved registers, so copy via a
9397 temporary. (This is the same code as used for SPARC.) */
9398 tree tmp = create_tmp_var (type, "va_arg_tmp");
9399 tree dest_addr = build_fold_addr_expr (tmp);
9401 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9402 3, dest_addr, addr, size_int (rsize * 4));
9404 gimplify_and_add (copy, pre_p);
9408 addr = fold_convert (ptrtype, addr);
9409 return build_va_arg_indirect_ref (addr);
9415 def_builtin (int mask, const char *name, tree type, int code)
9417 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9420 if (rs6000_builtin_decls[code])
9421 fatal_error ("internal error: builtin function to %s already processed",
9424 rs6000_builtin_decls[code] = t =
9425 add_builtin_function (name, type, code, BUILT_IN_MD,
9428 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9429 switch (builtin_classify[code])
9434 /* assume builtin can do anything. */
9435 case RS6000_BTC_MISC:
9438 /* const function, function only depends on the inputs. */
9439 case RS6000_BTC_CONST:
9440 TREE_READONLY (t) = 1;
9441 TREE_NOTHROW (t) = 1;
9444 /* pure function, function can read global memory. */
9445 case RS6000_BTC_PURE:
9446 DECL_PURE_P (t) = 1;
9447 TREE_NOTHROW (t) = 1;
9450 /* Function is a math function. If rounding mode is on, then treat
9451 the function as not reading global memory, but it can have
9452 arbitrary side effects. If it is off, then assume the function is
9453 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9454 attribute in builtin-attribute.def that is used for the math
9456 case RS6000_BTC_FP_PURE:
9457 TREE_NOTHROW (t) = 1;
9458 if (flag_rounding_math)
9460 DECL_PURE_P (t) = 1;
9461 DECL_IS_NOVOPS (t) = 1;
9464 TREE_READONLY (t) = 1;
9470 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9472 static const struct builtin_description bdesc_3arg[] =
9474 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9475 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9476 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9477 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9478 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9479 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9480 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9481 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9482 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9483 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9484 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9485 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9486 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9487 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9488 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9489 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9490 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9491 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9492 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9493 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9494 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9495 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9496 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9497 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9498 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9499 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9500 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9501 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9502 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9503 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9504 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9505 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9506 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9507 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9508 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9510 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9511 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9512 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9513 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9514 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9515 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9516 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9517 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9523 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9526 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9527 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9528 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9529 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9531 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9532 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9533 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9534 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9539 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9540 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9541 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9542 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9543 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9544 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9545 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9546 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9547 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9548 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9550 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9551 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9552 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9553 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9554 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9555 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9556 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9557 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9558 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9559 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9561 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9562 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9563 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9564 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9565 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9566 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9567 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9568 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9569 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9571 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9572 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9573 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9574 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9575 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9576 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9577 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9579 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9580 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9581 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9582 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9583 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9584 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9585 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9586 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9587 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9590 /* DST operations: void foo (void *, const int, const char). */
9592 static const struct builtin_description bdesc_dst[] =
9594 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9595 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9596 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9597 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9599 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9600 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9601 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9602 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9605 /* Simple binary operations: VECc = foo (VECa, VECb). */
9607 static struct builtin_description bdesc_2arg[] =
9609 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9610 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9611 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9612 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9614 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9615 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9620 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9621 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9622 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9623 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9624 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9631 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9632 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9633 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9634 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9635 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9636 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9637 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9638 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9639 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9640 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9641 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9642 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9643 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9644 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9645 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9646 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9647 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9648 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9649 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9650 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9651 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9652 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9653 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9654 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9655 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9656 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9657 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9658 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9659 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9660 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9661 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9662 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9663 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9664 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9665 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9666 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9667 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9668 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9669 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9670 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9671 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9672 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9673 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9674 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9675 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9676 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9677 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9678 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9679 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9680 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9681 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9682 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9683 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9684 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9685 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9686 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9687 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9688 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9689 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9690 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9691 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9692 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9693 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9694 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9695 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9696 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9697 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9698 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9699 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9700 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9701 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9702 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9703 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9704 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9705 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9706 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9707 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9708 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9709 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9710 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9711 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9712 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9713 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9714 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9715 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9716 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9717 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9718 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9719 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9720 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9721 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9722 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9723 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9724 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9725 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9727 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9728 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9729 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9730 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9731 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9732 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9733 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9734 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9735 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9736 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9737 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9738 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9740 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9741 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9742 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9743 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9744 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9745 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9746 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9747 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9748 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9749 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9750 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9751 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9753 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9754 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9755 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9756 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9757 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9758 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9760 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9761 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9762 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9763 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9764 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9765 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9766 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9767 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9768 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9769 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9770 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9771 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9773 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9774 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9786 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9787 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9813 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9814 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9829 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9830 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9847 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9848 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9882 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9883 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9901 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9903 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9904 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9906 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9907 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9908 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9909 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9910 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9911 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9912 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9913 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9914 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9915 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9917 /* Place holder, leave as first spe builtin. */
9918 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9919 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9920 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9921 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9922 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9923 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9924 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9925 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9926 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9927 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9928 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9929 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9930 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9931 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9932 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9933 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9934 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9935 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9936 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9937 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9938 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9939 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9940 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9941 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9942 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9943 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9944 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9945 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9946 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9947 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9948 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9949 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9950 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9951 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9952 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9953 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9954 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9955 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9956 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9957 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9958 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9959 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9960 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9961 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9962 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9963 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9964 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9965 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9966 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9967 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9968 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9969 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9970 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9971 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9972 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9973 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9974 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9975 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9976 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9977 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9978 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9979 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9980 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9981 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9982 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9983 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9984 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9985 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9986 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9987 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9988 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9989 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9990 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9991 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9992 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9993 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9994 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9995 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9996 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9997 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9998 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9999 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10000 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10001 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10002 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10003 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10004 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10005 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10006 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10007 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10008 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10009 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10010 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10011 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10012 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10013 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10014 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10015 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10016 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10017 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10018 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10019 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10020 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10021 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10022 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10023 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10024 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10025 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10026 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10028 /* SPE binary operations expecting a 5-bit unsigned literal. */
10029 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10031 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10032 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10033 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10034 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10035 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10036 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10037 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10038 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10039 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10040 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10041 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10042 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10043 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10044 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10045 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10046 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10047 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10048 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10049 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10050 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10051 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10052 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10053 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10054 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10055 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10056 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10058 /* Place-holder. Leave as last binary SPE builtin. */
10059 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10062 /* AltiVec predicates. */
10064 struct builtin_description_predicates
10066 const unsigned int mask;
10067 const enum insn_code icode;
10068 const char *const name;
10069 const enum rs6000_builtins code;
10072 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10074 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10075 ALTIVEC_BUILTIN_VCMPBFP_P },
10076 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10077 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10078 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10079 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10080 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10081 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10082 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10083 ALTIVEC_BUILTIN_VCMPEQUW_P },
10084 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10085 ALTIVEC_BUILTIN_VCMPGTSW_P },
10086 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10087 ALTIVEC_BUILTIN_VCMPGTUW_P },
10088 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10089 ALTIVEC_BUILTIN_VCMPEQUH_P },
10090 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10091 ALTIVEC_BUILTIN_VCMPGTSH_P },
10092 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10093 ALTIVEC_BUILTIN_VCMPGTUH_P },
10094 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10095 ALTIVEC_BUILTIN_VCMPEQUB_P },
10096 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10097 ALTIVEC_BUILTIN_VCMPGTSB_P },
10098 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10099 ALTIVEC_BUILTIN_VCMPGTUB_P },
10101 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10102 VSX_BUILTIN_XVCMPEQSP_P },
10103 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10104 VSX_BUILTIN_XVCMPGESP_P },
10105 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10106 VSX_BUILTIN_XVCMPGTSP_P },
10107 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10108 VSX_BUILTIN_XVCMPEQDP_P },
10109 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10110 VSX_BUILTIN_XVCMPGEDP_P },
10111 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10112 VSX_BUILTIN_XVCMPGTDP_P },
10114 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10115 ALTIVEC_BUILTIN_VCMPEQ_P },
10116 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10117 ALTIVEC_BUILTIN_VCMPGT_P },
10118 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10119 ALTIVEC_BUILTIN_VCMPGE_P }
10122 /* SPE predicates. */
10123 static struct builtin_description bdesc_spe_predicates[] =
10125 /* Place-holder. Leave as first. */
10126 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10127 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10128 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10129 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10130 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10131 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10132 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10133 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10134 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10135 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10136 /* Place-holder. Leave as last. */
10137 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10140 /* SPE evsel predicates. */
10141 static struct builtin_description bdesc_spe_evsel[] =
10143 /* Place-holder. Leave as first. */
10144 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10145 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10146 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10147 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10148 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10149 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10150 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10151 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10152 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10153 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10154 /* Place-holder. Leave as last. */
10155 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10158 /* PAIRED predicates. */
10159 static const struct builtin_description bdesc_paired_preds[] =
10161 /* Place-holder. Leave as first. */
10162 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10163 /* Place-holder. Leave as last. */
10164 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10167 /* ABS* operations. */
10169 static const struct builtin_description bdesc_abs[] =
10171 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10172 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10173 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10174 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10175 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10176 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10177 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10178 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10179 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10180 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10181 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10184 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10187 static struct builtin_description bdesc_1arg[] =
10189 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10190 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10191 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10192 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10193 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10194 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10195 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10196 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10197 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10198 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10199 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10200 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10201 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10202 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10203 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10204 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10205 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10206 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10208 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10209 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10210 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10211 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10212 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10213 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10214 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10216 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10217 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10218 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10219 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10220 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10221 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10222 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10224 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10225 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10226 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10227 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10228 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10229 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10231 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10232 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10233 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10234 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10235 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10236 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10238 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10239 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10240 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10241 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10243 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10244 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10245 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10246 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10247 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10248 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10249 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10250 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10251 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10253 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10254 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10255 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10256 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10257 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10258 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10259 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10260 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10261 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10263 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10264 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10265 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10266 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10267 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10285 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10286 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10287 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10288 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10290 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10291 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10292 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10294 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10295 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10296 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10297 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10299 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10300 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10301 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10302 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10303 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10304 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10305 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10306 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10307 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10308 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10309 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10310 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10311 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10312 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10313 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10314 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10315 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10316 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10317 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10318 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10319 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10320 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10321 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10322 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10323 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10324 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10325 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10326 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10327 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10328 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10330 /* Place-holder. Leave as last unary SPE builtin. */
10331 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10333 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10334 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10335 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10336 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10337 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10341 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10344 tree arg0 = CALL_EXPR_ARG (exp, 0);
10345 rtx op0 = expand_normal (arg0);
10346 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10347 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10349 if (icode == CODE_FOR_nothing)
10350 /* Builtin not supported on this processor. */
10353 /* If we got invalid arguments bail out before generating bad rtl. */
10354 if (arg0 == error_mark_node)
10357 if (icode == CODE_FOR_altivec_vspltisb
10358 || icode == CODE_FOR_altivec_vspltish
10359 || icode == CODE_FOR_altivec_vspltisw
10360 || icode == CODE_FOR_spe_evsplatfi
10361 || icode == CODE_FOR_spe_evsplati)
10363 /* Only allow 5-bit *signed* literals. */
10364 if (GET_CODE (op0) != CONST_INT
10365 || INTVAL (op0) > 15
10366 || INTVAL (op0) < -16)
10368 error ("argument 1 must be a 5-bit signed literal");
10374 || GET_MODE (target) != tmode
10375 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10376 target = gen_reg_rtx (tmode);
10378 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10379 op0 = copy_to_mode_reg (mode0, op0);
10381 pat = GEN_FCN (icode) (target, op0);
10390 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10392 rtx pat, scratch1, scratch2;
10393 tree arg0 = CALL_EXPR_ARG (exp, 0);
10394 rtx op0 = expand_normal (arg0);
10395 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10396 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10398 /* If we have invalid arguments, bail out before generating bad rtl. */
10399 if (arg0 == error_mark_node)
10403 || GET_MODE (target) != tmode
10404 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10405 target = gen_reg_rtx (tmode);
10407 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10408 op0 = copy_to_mode_reg (mode0, op0);
10410 scratch1 = gen_reg_rtx (mode0);
10411 scratch2 = gen_reg_rtx (mode0);
10413 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10422 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10425 tree arg0 = CALL_EXPR_ARG (exp, 0);
10426 tree arg1 = CALL_EXPR_ARG (exp, 1);
10427 rtx op0 = expand_normal (arg0);
10428 rtx op1 = expand_normal (arg1);
10429 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10430 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10431 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10433 if (icode == CODE_FOR_nothing)
10434 /* Builtin not supported on this processor. */
10437 /* If we got invalid arguments bail out before generating bad rtl. */
10438 if (arg0 == error_mark_node || arg1 == error_mark_node)
10441 if (icode == CODE_FOR_altivec_vcfux
10442 || icode == CODE_FOR_altivec_vcfsx
10443 || icode == CODE_FOR_altivec_vctsxs
10444 || icode == CODE_FOR_altivec_vctuxs
10445 || icode == CODE_FOR_altivec_vspltb
10446 || icode == CODE_FOR_altivec_vsplth
10447 || icode == CODE_FOR_altivec_vspltw
10448 || icode == CODE_FOR_spe_evaddiw
10449 || icode == CODE_FOR_spe_evldd
10450 || icode == CODE_FOR_spe_evldh
10451 || icode == CODE_FOR_spe_evldw
10452 || icode == CODE_FOR_spe_evlhhesplat
10453 || icode == CODE_FOR_spe_evlhhossplat
10454 || icode == CODE_FOR_spe_evlhhousplat
10455 || icode == CODE_FOR_spe_evlwhe
10456 || icode == CODE_FOR_spe_evlwhos
10457 || icode == CODE_FOR_spe_evlwhou
10458 || icode == CODE_FOR_spe_evlwhsplat
10459 || icode == CODE_FOR_spe_evlwwsplat
10460 || icode == CODE_FOR_spe_evrlwi
10461 || icode == CODE_FOR_spe_evslwi
10462 || icode == CODE_FOR_spe_evsrwis
10463 || icode == CODE_FOR_spe_evsubifw
10464 || icode == CODE_FOR_spe_evsrwiu)
10466 /* Only allow 5-bit unsigned literals. */
10468 if (TREE_CODE (arg1) != INTEGER_CST
10469 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10471 error ("argument 2 must be a 5-bit unsigned literal");
10477 || GET_MODE (target) != tmode
10478 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10479 target = gen_reg_rtx (tmode);
10481 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10482 op0 = copy_to_mode_reg (mode0, op0);
10483 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10484 op1 = copy_to_mode_reg (mode1, op1);
10486 pat = GEN_FCN (icode) (target, op0, op1);
10495 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10498 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10499 tree arg0 = CALL_EXPR_ARG (exp, 1);
10500 tree arg1 = CALL_EXPR_ARG (exp, 2);
10501 rtx op0 = expand_normal (arg0);
10502 rtx op1 = expand_normal (arg1);
10503 enum machine_mode tmode = SImode;
10504 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10505 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10508 if (TREE_CODE (cr6_form) != INTEGER_CST)
10510 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10514 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10516 gcc_assert (mode0 == mode1);
10518 /* If we have invalid arguments, bail out before generating bad rtl. */
10519 if (arg0 == error_mark_node || arg1 == error_mark_node)
10523 || GET_MODE (target) != tmode
10524 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10525 target = gen_reg_rtx (tmode);
10527 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10528 op0 = copy_to_mode_reg (mode0, op0);
10529 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10530 op1 = copy_to_mode_reg (mode1, op1);
10532 scratch = gen_reg_rtx (mode0);
10534 pat = GEN_FCN (icode) (scratch, op0, op1);
10539 /* The vec_any* and vec_all* predicates use the same opcodes for two
10540 different operations, but the bits in CR6 will be different
10541 depending on what information we want. So we have to play tricks
10542 with CR6 to get the right bits out.
10544 If you think this is disgusting, look at the specs for the
10545 AltiVec predicates. */
10547 switch (cr6_form_int)
10550 emit_insn (gen_cr6_test_for_zero (target));
10553 emit_insn (gen_cr6_test_for_zero_reverse (target));
10556 emit_insn (gen_cr6_test_for_lt (target));
10559 emit_insn (gen_cr6_test_for_lt_reverse (target));
10562 error ("argument 1 of __builtin_altivec_predicate is out of range");
10570 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10573 tree arg0 = CALL_EXPR_ARG (exp, 0);
10574 tree arg1 = CALL_EXPR_ARG (exp, 1);
10575 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10576 enum machine_mode mode0 = Pmode;
10577 enum machine_mode mode1 = Pmode;
10578 rtx op0 = expand_normal (arg0);
10579 rtx op1 = expand_normal (arg1);
10581 if (icode == CODE_FOR_nothing)
10582 /* Builtin not supported on this processor. */
10585 /* If we got invalid arguments bail out before generating bad rtl. */
10586 if (arg0 == error_mark_node || arg1 == error_mark_node)
10590 || GET_MODE (target) != tmode
10591 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10592 target = gen_reg_rtx (tmode);
10594 op1 = copy_to_mode_reg (mode1, op1);
10596 if (op0 == const0_rtx)
10598 addr = gen_rtx_MEM (tmode, op1);
10602 op0 = copy_to_mode_reg (mode0, op0);
10603 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10606 pat = GEN_FCN (icode) (target, addr);
10616 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10619 tree arg0 = CALL_EXPR_ARG (exp, 0);
10620 tree arg1 = CALL_EXPR_ARG (exp, 1);
10621 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10622 enum machine_mode mode0 = Pmode;
10623 enum machine_mode mode1 = Pmode;
10624 rtx op0 = expand_normal (arg0);
10625 rtx op1 = expand_normal (arg1);
10627 if (icode == CODE_FOR_nothing)
10628 /* Builtin not supported on this processor. */
10631 /* If we got invalid arguments bail out before generating bad rtl. */
10632 if (arg0 == error_mark_node || arg1 == error_mark_node)
10636 || GET_MODE (target) != tmode
10637 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10638 target = gen_reg_rtx (tmode);
10640 op1 = copy_to_mode_reg (mode1, op1);
10642 if (op0 == const0_rtx)
10644 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10648 op0 = copy_to_mode_reg (mode0, op0);
10649 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10652 pat = GEN_FCN (icode) (target, addr);
10662 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10664 tree arg0 = CALL_EXPR_ARG (exp, 0);
10665 tree arg1 = CALL_EXPR_ARG (exp, 1);
10666 tree arg2 = CALL_EXPR_ARG (exp, 2);
10667 rtx op0 = expand_normal (arg0);
10668 rtx op1 = expand_normal (arg1);
10669 rtx op2 = expand_normal (arg2);
10671 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10672 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10673 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10675 /* Invalid arguments. Bail before doing anything stoopid! */
10676 if (arg0 == error_mark_node
10677 || arg1 == error_mark_node
10678 || arg2 == error_mark_node)
10681 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10682 op0 = copy_to_mode_reg (mode2, op0);
10683 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10684 op1 = copy_to_mode_reg (mode0, op1);
10685 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10686 op2 = copy_to_mode_reg (mode1, op2);
10688 pat = GEN_FCN (icode) (op1, op2, op0);
10695 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10697 tree arg0 = CALL_EXPR_ARG (exp, 0);
10698 tree arg1 = CALL_EXPR_ARG (exp, 1);
10699 tree arg2 = CALL_EXPR_ARG (exp, 2);
10700 rtx op0 = expand_normal (arg0);
10701 rtx op1 = expand_normal (arg1);
10702 rtx op2 = expand_normal (arg2);
10704 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10705 enum machine_mode mode1 = Pmode;
10706 enum machine_mode mode2 = Pmode;
10708 /* Invalid arguments. Bail before doing anything stoopid! */
10709 if (arg0 == error_mark_node
10710 || arg1 == error_mark_node
10711 || arg2 == error_mark_node)
10714 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10715 op0 = copy_to_mode_reg (tmode, op0);
10717 op2 = copy_to_mode_reg (mode2, op2);
10719 if (op1 == const0_rtx)
10721 addr = gen_rtx_MEM (tmode, op2);
10725 op1 = copy_to_mode_reg (mode1, op1);
10726 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10729 pat = GEN_FCN (icode) (addr, op0);
10736 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10738 tree arg0 = CALL_EXPR_ARG (exp, 0);
10739 tree arg1 = CALL_EXPR_ARG (exp, 1);
10740 tree arg2 = CALL_EXPR_ARG (exp, 2);
10741 rtx op0 = expand_normal (arg0);
10742 rtx op1 = expand_normal (arg1);
10743 rtx op2 = expand_normal (arg2);
10745 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10746 enum machine_mode smode = insn_data[icode].operand[1].mode;
10747 enum machine_mode mode1 = Pmode;
10748 enum machine_mode mode2 = Pmode;
10750 /* Invalid arguments. Bail before doing anything stoopid! */
10751 if (arg0 == error_mark_node
10752 || arg1 == error_mark_node
10753 || arg2 == error_mark_node)
10756 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
10757 op0 = copy_to_mode_reg (smode, op0);
10759 op2 = copy_to_mode_reg (mode2, op2);
10761 if (op1 == const0_rtx)
10763 addr = gen_rtx_MEM (tmode, op2);
10767 op1 = copy_to_mode_reg (mode1, op1);
10768 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10771 pat = GEN_FCN (icode) (addr, op0);
10778 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10781 tree arg0 = CALL_EXPR_ARG (exp, 0);
10782 tree arg1 = CALL_EXPR_ARG (exp, 1);
10783 tree arg2 = CALL_EXPR_ARG (exp, 2);
10784 rtx op0 = expand_normal (arg0);
10785 rtx op1 = expand_normal (arg1);
10786 rtx op2 = expand_normal (arg2);
10787 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10788 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10789 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10790 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10792 if (icode == CODE_FOR_nothing)
10793 /* Builtin not supported on this processor. */
10796 /* If we got invalid arguments bail out before generating bad rtl. */
10797 if (arg0 == error_mark_node
10798 || arg1 == error_mark_node
10799 || arg2 == error_mark_node)
10802 /* Check and prepare argument depending on the instruction code.
10804 Note that a switch statement instead of the sequence of tests
10805 would be incorrect as many of the CODE_FOR values could be
10806 CODE_FOR_nothing and that would yield multiple alternatives
10807 with identical values. We'd never reach here at runtime in
10809 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10810 || icode == CODE_FOR_altivec_vsldoi_v4si
10811 || icode == CODE_FOR_altivec_vsldoi_v8hi
10812 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10814 /* Only allow 4-bit unsigned literals. */
10816 if (TREE_CODE (arg2) != INTEGER_CST
10817 || TREE_INT_CST_LOW (arg2) & ~0xf)
10819 error ("argument 3 must be a 4-bit unsigned literal");
10823 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10824 || icode == CODE_FOR_vsx_xxpermdi_v2di
10825 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10826 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10827 || icode == CODE_FOR_vsx_xxsldwi_v4si
10828 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10829 || icode == CODE_FOR_vsx_xxsldwi_v2di
10830 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10832 /* Only allow 2-bit unsigned literals. */
10834 if (TREE_CODE (arg2) != INTEGER_CST
10835 || TREE_INT_CST_LOW (arg2) & ~0x3)
10837 error ("argument 3 must be a 2-bit unsigned literal");
10841 else if (icode == CODE_FOR_vsx_set_v2df
10842 || icode == CODE_FOR_vsx_set_v2di)
10844 /* Only allow 1-bit unsigned literals. */
10846 if (TREE_CODE (arg2) != INTEGER_CST
10847 || TREE_INT_CST_LOW (arg2) & ~0x1)
10849 error ("argument 3 must be a 1-bit unsigned literal");
10855 || GET_MODE (target) != tmode
10856 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10857 target = gen_reg_rtx (tmode);
10859 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10860 op0 = copy_to_mode_reg (mode0, op0);
10861 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10862 op1 = copy_to_mode_reg (mode1, op1);
10863 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10864 op2 = copy_to_mode_reg (mode2, op2);
10866 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10867 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10869 pat = GEN_FCN (icode) (target, op0, op1, op2);
10877 /* Expand the lvx builtins. */
10879 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10881 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10882 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10884 enum machine_mode tmode, mode0;
10886 enum insn_code icode;
10890 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10891 icode = CODE_FOR_vector_altivec_load_v16qi;
10893 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10894 icode = CODE_FOR_vector_altivec_load_v8hi;
10896 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10897 icode = CODE_FOR_vector_altivec_load_v4si;
10899 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10900 icode = CODE_FOR_vector_altivec_load_v4sf;
10902 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
10903 icode = CODE_FOR_vector_altivec_load_v2df;
10905 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
10906 icode = CODE_FOR_vector_altivec_load_v2di;
10909 *expandedp = false;
10915 arg0 = CALL_EXPR_ARG (exp, 0);
10916 op0 = expand_normal (arg0);
10917 tmode = insn_data[icode].operand[0].mode;
10918 mode0 = insn_data[icode].operand[1].mode;
10921 || GET_MODE (target) != tmode
10922 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10923 target = gen_reg_rtx (tmode);
10925 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10926 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10928 pat = GEN_FCN (icode) (target, op0);
10935 /* Expand the stvx builtins. */
10937 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10940 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10941 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10943 enum machine_mode mode0, mode1;
10945 enum insn_code icode;
10949 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10950 icode = CODE_FOR_vector_altivec_store_v16qi;
10952 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10953 icode = CODE_FOR_vector_altivec_store_v8hi;
10955 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10956 icode = CODE_FOR_vector_altivec_store_v4si;
10958 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10959 icode = CODE_FOR_vector_altivec_store_v4sf;
10961 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
10962 icode = CODE_FOR_vector_altivec_store_v2df;
10964 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
10965 icode = CODE_FOR_vector_altivec_store_v2di;
10968 *expandedp = false;
10972 arg0 = CALL_EXPR_ARG (exp, 0);
10973 arg1 = CALL_EXPR_ARG (exp, 1);
10974 op0 = expand_normal (arg0);
10975 op1 = expand_normal (arg1);
10976 mode0 = insn_data[icode].operand[0].mode;
10977 mode1 = insn_data[icode].operand[1].mode;
10979 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10980 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10981 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10982 op1 = copy_to_mode_reg (mode1, op1);
10984 pat = GEN_FCN (icode) (op0, op1);
10992 /* Expand the dst builtins. */
10994 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10997 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10998 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10999 tree arg0, arg1, arg2;
11000 enum machine_mode mode0, mode1;
11001 rtx pat, op0, op1, op2;
11002 const struct builtin_description *d;
11005 *expandedp = false;
11007 /* Handle DST variants. */
11009 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11010 if (d->code == fcode)
11012 arg0 = CALL_EXPR_ARG (exp, 0);
11013 arg1 = CALL_EXPR_ARG (exp, 1);
11014 arg2 = CALL_EXPR_ARG (exp, 2);
11015 op0 = expand_normal (arg0);
11016 op1 = expand_normal (arg1);
11017 op2 = expand_normal (arg2);
11018 mode0 = insn_data[d->icode].operand[0].mode;
11019 mode1 = insn_data[d->icode].operand[1].mode;
11021 /* Invalid arguments, bail out before generating bad rtl. */
11022 if (arg0 == error_mark_node
11023 || arg1 == error_mark_node
11024 || arg2 == error_mark_node)
11029 if (TREE_CODE (arg2) != INTEGER_CST
11030 || TREE_INT_CST_LOW (arg2) & ~0x3)
11032 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11036 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11037 op0 = copy_to_mode_reg (Pmode, op0);
11038 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11039 op1 = copy_to_mode_reg (mode1, op1);
11041 pat = GEN_FCN (d->icode) (op0, op1, op2);
11051 /* Expand vec_init builtin. */
11053 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11055 enum machine_mode tmode = TYPE_MODE (type);
11056 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11057 int i, n_elt = GET_MODE_NUNITS (tmode);
11058 rtvec v = rtvec_alloc (n_elt);
11060 gcc_assert (VECTOR_MODE_P (tmode));
11061 gcc_assert (n_elt == call_expr_nargs (exp));
11063 for (i = 0; i < n_elt; ++i)
11065 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11066 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11069 if (!target || !register_operand (target, tmode))
11070 target = gen_reg_rtx (tmode);
11072 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11076 /* Return the integer constant in ARG. Constrain it to be in the range
11077 of the subparts of VEC_TYPE; issue an error if not. */
11080 get_element_number (tree vec_type, tree arg)
11082 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11084 if (!host_integerp (arg, 1)
11085 || (elt = tree_low_cst (arg, 1), elt > max))
11087 error ("selector must be an integer constant in the range 0..%wi", max);
11094 /* Expand vec_set builtin. */
11096 altivec_expand_vec_set_builtin (tree exp)
11098 enum machine_mode tmode, mode1;
11099 tree arg0, arg1, arg2;
11103 arg0 = CALL_EXPR_ARG (exp, 0);
11104 arg1 = CALL_EXPR_ARG (exp, 1);
11105 arg2 = CALL_EXPR_ARG (exp, 2);
11107 tmode = TYPE_MODE (TREE_TYPE (arg0));
11108 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11109 gcc_assert (VECTOR_MODE_P (tmode));
11111 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11112 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11113 elt = get_element_number (TREE_TYPE (arg0), arg2);
11115 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11116 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11118 op0 = force_reg (tmode, op0);
11119 op1 = force_reg (mode1, op1);
11121 rs6000_expand_vector_set (op0, op1, elt);
11126 /* Expand vec_ext builtin. */
11128 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11130 enum machine_mode tmode, mode0;
11135 arg0 = CALL_EXPR_ARG (exp, 0);
11136 arg1 = CALL_EXPR_ARG (exp, 1);
11138 op0 = expand_normal (arg0);
11139 elt = get_element_number (TREE_TYPE (arg0), arg1);
11141 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11142 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11143 gcc_assert (VECTOR_MODE_P (mode0));
11145 op0 = force_reg (mode0, op0);
11147 if (optimize || !target || !register_operand (target, tmode))
11148 target = gen_reg_rtx (tmode);
11150 rs6000_expand_vector_extract (target, op0, elt);
11155 /* Expand the builtin in EXP and store the result in TARGET. Store
11156 true in *EXPANDEDP if we found a builtin to expand. */
11158 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11160 const struct builtin_description *d;
11161 const struct builtin_description_predicates *dp;
11163 enum insn_code icode;
11164 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11167 enum machine_mode tmode, mode0;
11168 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11170 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11171 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11172 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11173 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11176 error ("unresolved overload for Altivec builtin %qF", fndecl);
11180 target = altivec_expand_ld_builtin (exp, target, expandedp);
11184 target = altivec_expand_st_builtin (exp, target, expandedp);
11188 target = altivec_expand_dst_builtin (exp, target, expandedp);
11196 case ALTIVEC_BUILTIN_STVX:
11197 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11198 case ALTIVEC_BUILTIN_STVEBX:
11199 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11200 case ALTIVEC_BUILTIN_STVEHX:
11201 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11202 case ALTIVEC_BUILTIN_STVEWX:
11203 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11204 case ALTIVEC_BUILTIN_STVXL:
11205 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11207 case ALTIVEC_BUILTIN_STVLX:
11208 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11209 case ALTIVEC_BUILTIN_STVLXL:
11210 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11211 case ALTIVEC_BUILTIN_STVRX:
11212 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11213 case ALTIVEC_BUILTIN_STVRXL:
11214 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11216 case VSX_BUILTIN_STXVD2X_V2DF:
11217 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11218 case VSX_BUILTIN_STXVD2X_V2DI:
11219 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11220 case VSX_BUILTIN_STXVW4X_V4SF:
11221 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11222 case VSX_BUILTIN_STXVW4X_V4SI:
11223 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11224 case VSX_BUILTIN_STXVW4X_V8HI:
11225 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11226 case VSX_BUILTIN_STXVW4X_V16QI:
11227 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11229 case ALTIVEC_BUILTIN_MFVSCR:
11230 icode = CODE_FOR_altivec_mfvscr;
11231 tmode = insn_data[icode].operand[0].mode;
11234 || GET_MODE (target) != tmode
11235 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11236 target = gen_reg_rtx (tmode);
11238 pat = GEN_FCN (icode) (target);
11244 case ALTIVEC_BUILTIN_MTVSCR:
11245 icode = CODE_FOR_altivec_mtvscr;
11246 arg0 = CALL_EXPR_ARG (exp, 0);
11247 op0 = expand_normal (arg0);
11248 mode0 = insn_data[icode].operand[0].mode;
11250 /* If we got invalid arguments bail out before generating bad rtl. */
11251 if (arg0 == error_mark_node)
11254 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11255 op0 = copy_to_mode_reg (mode0, op0);
11257 pat = GEN_FCN (icode) (op0);
11262 case ALTIVEC_BUILTIN_DSSALL:
11263 emit_insn (gen_altivec_dssall ());
11266 case ALTIVEC_BUILTIN_DSS:
11267 icode = CODE_FOR_altivec_dss;
11268 arg0 = CALL_EXPR_ARG (exp, 0);
11270 op0 = expand_normal (arg0);
11271 mode0 = insn_data[icode].operand[0].mode;
11273 /* If we got invalid arguments bail out before generating bad rtl. */
11274 if (arg0 == error_mark_node)
11277 if (TREE_CODE (arg0) != INTEGER_CST
11278 || TREE_INT_CST_LOW (arg0) & ~0x3)
11280 error ("argument to dss must be a 2-bit unsigned literal");
11284 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11285 op0 = copy_to_mode_reg (mode0, op0);
11287 emit_insn (gen_altivec_dss (op0));
11290 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11291 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11292 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11293 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11294 case VSX_BUILTIN_VEC_INIT_V2DF:
11295 case VSX_BUILTIN_VEC_INIT_V2DI:
11296 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11298 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11299 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11300 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11301 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11302 case VSX_BUILTIN_VEC_SET_V2DF:
11303 case VSX_BUILTIN_VEC_SET_V2DI:
11304 return altivec_expand_vec_set_builtin (exp);
11306 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11307 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11308 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11309 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11310 case VSX_BUILTIN_VEC_EXT_V2DF:
11311 case VSX_BUILTIN_VEC_EXT_V2DI:
11312 return altivec_expand_vec_ext_builtin (exp, target);
11316 /* Fall through. */
11319 /* Expand abs* operations. */
11321 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11322 if (d->code == fcode)
11323 return altivec_expand_abs_builtin (d->icode, exp, target);
11325 /* Expand the AltiVec predicates. */
11326 dp = bdesc_altivec_preds;
11327 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11328 if (dp->code == fcode)
11329 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11331 /* LV* are funky. We initialized them differently. */
11334 case ALTIVEC_BUILTIN_LVSL:
11335 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11336 exp, target, false);
11337 case ALTIVEC_BUILTIN_LVSR:
11338 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11339 exp, target, false);
11340 case ALTIVEC_BUILTIN_LVEBX:
11341 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11342 exp, target, false);
11343 case ALTIVEC_BUILTIN_LVEHX:
11344 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11345 exp, target, false);
11346 case ALTIVEC_BUILTIN_LVEWX:
11347 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11348 exp, target, false);
11349 case ALTIVEC_BUILTIN_LVXL:
11350 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11351 exp, target, false);
11352 case ALTIVEC_BUILTIN_LVX:
11353 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11354 exp, target, false);
11355 case ALTIVEC_BUILTIN_LVLX:
11356 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11357 exp, target, true);
11358 case ALTIVEC_BUILTIN_LVLXL:
11359 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11360 exp, target, true);
11361 case ALTIVEC_BUILTIN_LVRX:
11362 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11363 exp, target, true);
11364 case ALTIVEC_BUILTIN_LVRXL:
11365 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11366 exp, target, true);
11367 case VSX_BUILTIN_LXVD2X_V2DF:
11368 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11369 exp, target, false);
11370 case VSX_BUILTIN_LXVD2X_V2DI:
11371 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11372 exp, target, false);
11373 case VSX_BUILTIN_LXVW4X_V4SF:
11374 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11375 exp, target, false);
11376 case VSX_BUILTIN_LXVW4X_V4SI:
11377 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11378 exp, target, false);
11379 case VSX_BUILTIN_LXVW4X_V8HI:
11380 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11381 exp, target, false);
11382 case VSX_BUILTIN_LXVW4X_V16QI:
11383 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11384 exp, target, false);
11388 /* Fall through. */
11391 *expandedp = false;
11395 /* Expand the builtin in EXP and store the result in TARGET. Store
11396 true in *EXPANDEDP if we found a builtin to expand. */
11398 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11400 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11401 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11402 const struct builtin_description *d;
11409 case PAIRED_BUILTIN_STX:
11410 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11411 case PAIRED_BUILTIN_LX:
11412 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11415 /* Fall through. */
11418 /* Expand the paired predicates. */
11419 d = bdesc_paired_preds;
11420 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11421 if (d->code == fcode)
11422 return paired_expand_predicate_builtin (d->icode, exp, target);
11424 *expandedp = false;
11428 /* Binops that need to be initialized manually, but can be expanded
11429 automagically by rs6000_expand_binop_builtin. */
11430 static struct builtin_description bdesc_2arg_spe[] =
11432 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11433 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11434 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11435 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11436 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11437 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11438 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11439 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11440 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11441 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11442 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11443 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11444 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11445 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11446 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11447 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11448 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11449 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11450 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11451 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11452 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11453 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11456 /* Expand the builtin in EXP and store the result in TARGET. Store
11457 true in *EXPANDEDP if we found a builtin to expand.
11459 This expands the SPE builtins that are not simple unary and binary
11462 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11464 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11466 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11467 enum insn_code icode;
11468 enum machine_mode tmode, mode0;
11470 struct builtin_description *d;
11475 /* Syntax check for a 5-bit unsigned immediate. */
11478 case SPE_BUILTIN_EVSTDD:
11479 case SPE_BUILTIN_EVSTDH:
11480 case SPE_BUILTIN_EVSTDW:
11481 case SPE_BUILTIN_EVSTWHE:
11482 case SPE_BUILTIN_EVSTWHO:
11483 case SPE_BUILTIN_EVSTWWE:
11484 case SPE_BUILTIN_EVSTWWO:
11485 arg1 = CALL_EXPR_ARG (exp, 2);
11486 if (TREE_CODE (arg1) != INTEGER_CST
11487 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11489 error ("argument 2 must be a 5-bit unsigned literal");
11497 /* The evsplat*i instructions are not quite generic. */
11500 case SPE_BUILTIN_EVSPLATFI:
11501 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11503 case SPE_BUILTIN_EVSPLATI:
11504 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11510 d = (struct builtin_description *) bdesc_2arg_spe;
11511 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11512 if (d->code == fcode)
11513 return rs6000_expand_binop_builtin (d->icode, exp, target);
11515 d = (struct builtin_description *) bdesc_spe_predicates;
11516 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11517 if (d->code == fcode)
11518 return spe_expand_predicate_builtin (d->icode, exp, target);
11520 d = (struct builtin_description *) bdesc_spe_evsel;
11521 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11522 if (d->code == fcode)
11523 return spe_expand_evsel_builtin (d->icode, exp, target);
11527 case SPE_BUILTIN_EVSTDDX:
11528 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11529 case SPE_BUILTIN_EVSTDHX:
11530 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11531 case SPE_BUILTIN_EVSTDWX:
11532 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11533 case SPE_BUILTIN_EVSTWHEX:
11534 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11535 case SPE_BUILTIN_EVSTWHOX:
11536 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11537 case SPE_BUILTIN_EVSTWWEX:
11538 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11539 case SPE_BUILTIN_EVSTWWOX:
11540 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11541 case SPE_BUILTIN_EVSTDD:
11542 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11543 case SPE_BUILTIN_EVSTDH:
11544 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11545 case SPE_BUILTIN_EVSTDW:
11546 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11547 case SPE_BUILTIN_EVSTWHE:
11548 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11549 case SPE_BUILTIN_EVSTWHO:
11550 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11551 case SPE_BUILTIN_EVSTWWE:
11552 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11553 case SPE_BUILTIN_EVSTWWO:
11554 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11555 case SPE_BUILTIN_MFSPEFSCR:
11556 icode = CODE_FOR_spe_mfspefscr;
11557 tmode = insn_data[icode].operand[0].mode;
11560 || GET_MODE (target) != tmode
11561 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11562 target = gen_reg_rtx (tmode);
11564 pat = GEN_FCN (icode) (target);
11569 case SPE_BUILTIN_MTSPEFSCR:
11570 icode = CODE_FOR_spe_mtspefscr;
11571 arg0 = CALL_EXPR_ARG (exp, 0);
11572 op0 = expand_normal (arg0);
11573 mode0 = insn_data[icode].operand[0].mode;
11575 if (arg0 == error_mark_node)
11578 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11579 op0 = copy_to_mode_reg (mode0, op0);
11581 pat = GEN_FCN (icode) (op0);
11589 *expandedp = false;
11594 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11596 rtx pat, scratch, tmp;
11597 tree form = CALL_EXPR_ARG (exp, 0);
11598 tree arg0 = CALL_EXPR_ARG (exp, 1);
11599 tree arg1 = CALL_EXPR_ARG (exp, 2);
11600 rtx op0 = expand_normal (arg0);
11601 rtx op1 = expand_normal (arg1);
11602 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11603 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11605 enum rtx_code code;
11607 if (TREE_CODE (form) != INTEGER_CST)
11609 error ("argument 1 of __builtin_paired_predicate must be a constant");
11613 form_int = TREE_INT_CST_LOW (form);
11615 gcc_assert (mode0 == mode1);
11617 if (arg0 == error_mark_node || arg1 == error_mark_node)
11621 || GET_MODE (target) != SImode
11622 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11623 target = gen_reg_rtx (SImode);
11624 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11625 op0 = copy_to_mode_reg (mode0, op0);
11626 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11627 op1 = copy_to_mode_reg (mode1, op1);
11629 scratch = gen_reg_rtx (CCFPmode);
11631 pat = GEN_FCN (icode) (scratch, op0, op1);
11653 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11656 error ("argument 1 of __builtin_paired_predicate is out of range");
11660 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11661 emit_move_insn (target, tmp);
11666 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11668 rtx pat, scratch, tmp;
11669 tree form = CALL_EXPR_ARG (exp, 0);
11670 tree arg0 = CALL_EXPR_ARG (exp, 1);
11671 tree arg1 = CALL_EXPR_ARG (exp, 2);
11672 rtx op0 = expand_normal (arg0);
11673 rtx op1 = expand_normal (arg1);
11674 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11675 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11677 enum rtx_code code;
11679 if (TREE_CODE (form) != INTEGER_CST)
11681 error ("argument 1 of __builtin_spe_predicate must be a constant");
11685 form_int = TREE_INT_CST_LOW (form);
11687 gcc_assert (mode0 == mode1);
11689 if (arg0 == error_mark_node || arg1 == error_mark_node)
11693 || GET_MODE (target) != SImode
11694 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11695 target = gen_reg_rtx (SImode);
11697 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11698 op0 = copy_to_mode_reg (mode0, op0);
11699 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11700 op1 = copy_to_mode_reg (mode1, op1);
11702 scratch = gen_reg_rtx (CCmode);
11704 pat = GEN_FCN (icode) (scratch, op0, op1);
11709 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11710 _lower_. We use one compare, but look in different bits of the
11711 CR for each variant.
11713 There are 2 elements in each SPE simd type (upper/lower). The CR
11714 bits are set as follows:
11716 BIT0 | BIT 1 | BIT 2 | BIT 3
11717 U | L | (U | L) | (U & L)
11719 So, for an "all" relationship, BIT 3 would be set.
11720 For an "any" relationship, BIT 2 would be set. Etc.
11722 Following traditional nomenclature, these bits map to:
11724 BIT0 | BIT 1 | BIT 2 | BIT 3
11727 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11732 /* All variant. OV bit. */
11734 /* We need to get to the OV bit, which is the ORDERED bit. We
11735 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11736 that's ugly and will make validate_condition_mode die.
11737 So let's just use another pattern. */
11738 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11740 /* Any variant. EQ bit. */
11744 /* Upper variant. LT bit. */
11748 /* Lower variant. GT bit. */
11753 error ("argument 1 of __builtin_spe_predicate is out of range");
11757 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11758 emit_move_insn (target, tmp);
11763 /* The evsel builtins look like this:
11765 e = __builtin_spe_evsel_OP (a, b, c, d);
11767 and work like this:
11769 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11770 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11774 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11777 tree arg0 = CALL_EXPR_ARG (exp, 0);
11778 tree arg1 = CALL_EXPR_ARG (exp, 1);
11779 tree arg2 = CALL_EXPR_ARG (exp, 2);
11780 tree arg3 = CALL_EXPR_ARG (exp, 3);
11781 rtx op0 = expand_normal (arg0);
11782 rtx op1 = expand_normal (arg1);
11783 rtx op2 = expand_normal (arg2);
11784 rtx op3 = expand_normal (arg3);
11785 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11786 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11788 gcc_assert (mode0 == mode1);
11790 if (arg0 == error_mark_node || arg1 == error_mark_node
11791 || arg2 == error_mark_node || arg3 == error_mark_node)
11795 || GET_MODE (target) != mode0
11796 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11797 target = gen_reg_rtx (mode0);
11799 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11800 op0 = copy_to_mode_reg (mode0, op0);
11801 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11802 op1 = copy_to_mode_reg (mode0, op1);
11803 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11804 op2 = copy_to_mode_reg (mode0, op2);
11805 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11806 op3 = copy_to_mode_reg (mode0, op3);
11808 /* Generate the compare. */
11809 scratch = gen_reg_rtx (CCmode);
11810 pat = GEN_FCN (icode) (scratch, op0, op1);
11815 if (mode0 == V2SImode)
11816 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11818 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11823 /* Expand an expression EXP that calls a built-in function,
11824 with result going to TARGET if that's convenient
11825 (and in mode MODE if that's convenient).
11826 SUBTARGET may be used as the target for computing one of EXP's operands.
11827 IGNORE is nonzero if the value is to be ignored. */
11830 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11831 enum machine_mode mode ATTRIBUTE_UNUSED,
11832 int ignore ATTRIBUTE_UNUSED)
11834 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11835 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11836 const struct builtin_description *d;
11843 case RS6000_BUILTIN_RECIP:
11844 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11846 case RS6000_BUILTIN_RECIPF:
11847 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11849 case RS6000_BUILTIN_RSQRTF:
11850 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11852 case RS6000_BUILTIN_RSQRT:
11853 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11855 case RS6000_BUILTIN_BSWAP_HI:
11856 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11858 case POWER7_BUILTIN_BPERMD:
11859 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11860 ? CODE_FOR_bpermd_di
11861 : CODE_FOR_bpermd_si), exp, target);
11863 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11864 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11866 int icode = (int) CODE_FOR_altivec_lvsr;
11867 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11868 enum machine_mode mode = insn_data[icode].operand[1].mode;
11872 gcc_assert (TARGET_ALTIVEC);
11874 arg = CALL_EXPR_ARG (exp, 0);
11875 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11876 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11877 addr = memory_address (mode, op);
11878 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11882 /* For the load case need to negate the address. */
11883 op = gen_reg_rtx (GET_MODE (addr));
11884 emit_insn (gen_rtx_SET (VOIDmode, op,
11885 gen_rtx_NEG (GET_MODE (addr), addr)));
11887 op = gen_rtx_MEM (mode, op);
11890 || GET_MODE (target) != tmode
11891 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11892 target = gen_reg_rtx (tmode);
11894 /*pat = gen_altivec_lvsr (target, op);*/
11895 pat = GEN_FCN (icode) (target, op);
11903 case ALTIVEC_BUILTIN_VCFUX:
11904 case ALTIVEC_BUILTIN_VCFSX:
11905 case ALTIVEC_BUILTIN_VCTUXS:
11906 case ALTIVEC_BUILTIN_VCTSXS:
11907 /* FIXME: There's got to be a nicer way to handle this case than
11908 constructing a new CALL_EXPR. */
11909 if (call_expr_nargs (exp) == 1)
11911 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11912 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11920 if (TARGET_ALTIVEC)
11922 ret = altivec_expand_builtin (exp, target, &success);
11929 ret = spe_expand_builtin (exp, target, &success);
11934 if (TARGET_PAIRED_FLOAT)
11936 ret = paired_expand_builtin (exp, target, &success);
11942 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11944 /* Handle simple unary operations. */
11945 d = (struct builtin_description *) bdesc_1arg;
11946 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11947 if (d->code == fcode)
11948 return rs6000_expand_unop_builtin (d->icode, exp, target);
11950 /* Handle simple binary operations. */
11951 d = (struct builtin_description *) bdesc_2arg;
11952 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11953 if (d->code == fcode)
11954 return rs6000_expand_binop_builtin (d->icode, exp, target);
11956 /* Handle simple ternary operations. */
11958 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11959 if (d->code == fcode)
11960 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11962 gcc_unreachable ();
11966 rs6000_init_builtins (void)
11971 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11972 V2SF_type_node = build_vector_type (float_type_node, 2);
11973 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11974 V2DF_type_node = build_vector_type (double_type_node, 2);
11975 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11976 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11977 V4SF_type_node = build_vector_type (float_type_node, 4);
11978 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11979 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11981 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11982 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11983 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11984 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11986 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11987 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11988 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11989 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11991 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11992 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11993 'vector unsigned short'. */
11995 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11996 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11997 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11998 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11999 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12001 long_integer_type_internal_node = long_integer_type_node;
12002 long_unsigned_type_internal_node = long_unsigned_type_node;
12003 long_long_integer_type_internal_node = long_long_integer_type_node;
12004 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12005 intQI_type_internal_node = intQI_type_node;
12006 uintQI_type_internal_node = unsigned_intQI_type_node;
12007 intHI_type_internal_node = intHI_type_node;
12008 uintHI_type_internal_node = unsigned_intHI_type_node;
12009 intSI_type_internal_node = intSI_type_node;
12010 uintSI_type_internal_node = unsigned_intSI_type_node;
12011 intDI_type_internal_node = intDI_type_node;
12012 uintDI_type_internal_node = unsigned_intDI_type_node;
12013 float_type_internal_node = float_type_node;
12014 double_type_internal_node = double_type_node;
12015 void_type_internal_node = void_type_node;
12017 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12019 builtin_mode_to_type[QImode][0] = integer_type_node;
12020 builtin_mode_to_type[HImode][0] = integer_type_node;
12021 builtin_mode_to_type[SImode][0] = intSI_type_node;
12022 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12023 builtin_mode_to_type[DImode][0] = intDI_type_node;
12024 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12025 builtin_mode_to_type[SFmode][0] = float_type_node;
12026 builtin_mode_to_type[DFmode][0] = double_type_node;
12027 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12028 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12029 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12030 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12031 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12032 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12033 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12034 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12035 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12036 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12037 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12038 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12039 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12041 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12042 get_identifier ("__bool char"),
12043 bool_char_type_node);
12044 TYPE_NAME (bool_char_type_node) = tdecl;
12045 (*lang_hooks.decls.pushdecl) (tdecl);
12046 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12047 get_identifier ("__bool short"),
12048 bool_short_type_node);
12049 TYPE_NAME (bool_short_type_node) = tdecl;
12050 (*lang_hooks.decls.pushdecl) (tdecl);
12051 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12052 get_identifier ("__bool int"),
12053 bool_int_type_node);
12054 TYPE_NAME (bool_int_type_node) = tdecl;
12055 (*lang_hooks.decls.pushdecl) (tdecl);
12056 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12058 TYPE_NAME (pixel_type_node) = tdecl;
12059 (*lang_hooks.decls.pushdecl) (tdecl);
12061 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12062 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12063 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12064 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12065 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12067 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12068 get_identifier ("__vector unsigned char"),
12069 unsigned_V16QI_type_node);
12070 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12071 (*lang_hooks.decls.pushdecl) (tdecl);
12072 tdecl = build_decl (BUILTINS_LOCATION,
12073 TYPE_DECL, get_identifier ("__vector signed char"),
12075 TYPE_NAME (V16QI_type_node) = tdecl;
12076 (*lang_hooks.decls.pushdecl) (tdecl);
12077 tdecl = build_decl (BUILTINS_LOCATION,
12078 TYPE_DECL, get_identifier ("__vector __bool char"),
12079 bool_V16QI_type_node);
12080 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12081 (*lang_hooks.decls.pushdecl) (tdecl);
12083 tdecl = build_decl (BUILTINS_LOCATION,
12084 TYPE_DECL, get_identifier ("__vector unsigned short"),
12085 unsigned_V8HI_type_node);
12086 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12087 (*lang_hooks.decls.pushdecl) (tdecl);
12088 tdecl = build_decl (BUILTINS_LOCATION,
12089 TYPE_DECL, get_identifier ("__vector signed short"),
12091 TYPE_NAME (V8HI_type_node) = tdecl;
12092 (*lang_hooks.decls.pushdecl) (tdecl);
12093 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12094 get_identifier ("__vector __bool short"),
12095 bool_V8HI_type_node);
12096 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12097 (*lang_hooks.decls.pushdecl) (tdecl);
12099 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12100 get_identifier ("__vector unsigned int"),
12101 unsigned_V4SI_type_node);
12102 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12103 (*lang_hooks.decls.pushdecl) (tdecl);
12104 tdecl = build_decl (BUILTINS_LOCATION,
12105 TYPE_DECL, get_identifier ("__vector signed int"),
12107 TYPE_NAME (V4SI_type_node) = tdecl;
12108 (*lang_hooks.decls.pushdecl) (tdecl);
12109 tdecl = build_decl (BUILTINS_LOCATION,
12110 TYPE_DECL, get_identifier ("__vector __bool int"),
12111 bool_V4SI_type_node);
12112 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12113 (*lang_hooks.decls.pushdecl) (tdecl);
12115 tdecl = build_decl (BUILTINS_LOCATION,
12116 TYPE_DECL, get_identifier ("__vector float"),
12118 TYPE_NAME (V4SF_type_node) = tdecl;
12119 (*lang_hooks.decls.pushdecl) (tdecl);
12120 tdecl = build_decl (BUILTINS_LOCATION,
12121 TYPE_DECL, get_identifier ("__vector __pixel"),
12122 pixel_V8HI_type_node);
12123 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12124 (*lang_hooks.decls.pushdecl) (tdecl);
12128 tdecl = build_decl (BUILTINS_LOCATION,
12129 TYPE_DECL, get_identifier ("__vector double"),
12131 TYPE_NAME (V2DF_type_node) = tdecl;
12132 (*lang_hooks.decls.pushdecl) (tdecl);
12134 tdecl = build_decl (BUILTINS_LOCATION,
12135 TYPE_DECL, get_identifier ("__vector long"),
12137 TYPE_NAME (V2DI_type_node) = tdecl;
12138 (*lang_hooks.decls.pushdecl) (tdecl);
12140 tdecl = build_decl (BUILTINS_LOCATION,
12141 TYPE_DECL, get_identifier ("__vector unsigned long"),
12142 unsigned_V2DI_type_node);
12143 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12144 (*lang_hooks.decls.pushdecl) (tdecl);
12146 tdecl = build_decl (BUILTINS_LOCATION,
12147 TYPE_DECL, get_identifier ("__vector __bool long"),
12148 bool_V2DI_type_node);
12149 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12150 (*lang_hooks.decls.pushdecl) (tdecl);
12153 if (TARGET_PAIRED_FLOAT)
12154 paired_init_builtins ();
12156 spe_init_builtins ();
12157 if (TARGET_ALTIVEC)
12158 altivec_init_builtins ();
12159 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12160 rs6000_common_init_builtins ();
12163 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12164 RS6000_BUILTIN_RECIP,
12165 "__builtin_recipdiv");
12166 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12167 RS6000_BUILTIN_RECIP);
12171 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12172 RS6000_BUILTIN_RECIPF,
12173 "__builtin_recipdivf");
12174 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12175 RS6000_BUILTIN_RECIPF);
12177 if (TARGET_FRSQRTE)
12179 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12180 RS6000_BUILTIN_RSQRT,
12181 "__builtin_rsqrt");
12182 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12183 RS6000_BUILTIN_RSQRT);
12185 if (TARGET_FRSQRTES)
12187 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12188 RS6000_BUILTIN_RSQRTF,
12189 "__builtin_rsqrtf");
12190 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12191 RS6000_BUILTIN_RSQRTF);
12193 if (TARGET_POPCNTD)
12195 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12196 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12197 POWER7_BUILTIN_BPERMD,
12198 "__builtin_bpermd");
12199 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12200 POWER7_BUILTIN_BPERMD);
12202 if (TARGET_POWERPC)
12204 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12205 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12206 unsigned_intHI_type_node,
12208 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12209 RS6000_BUILTIN_BSWAP_HI);
12213 /* AIX libm provides clog as __clog. */
12214 if (built_in_decls [BUILT_IN_CLOG])
12215 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12218 #ifdef SUBTARGET_INIT_BUILTINS
12219 SUBTARGET_INIT_BUILTINS;
12223 /* Returns the rs6000 builtin decl for CODE. */
12226 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12228 if (code >= RS6000_BUILTIN_COUNT)
12229 return error_mark_node;
12231 return rs6000_builtin_decls[code];
12234 /* Search through a set of builtins and enable the mask bits.
12235 DESC is an array of builtins.
12236 SIZE is the total number of builtins.
12237 START is the builtin enum at which to start.
12238 END is the builtin enum at which to end. */
12240 enable_mask_for_builtins (struct builtin_description *desc, int size,
12241 enum rs6000_builtins start,
12242 enum rs6000_builtins end)
12246 for (i = 0; i < size; ++i)
12247 if (desc[i].code == start)
12253 for (; i < size; ++i)
12255 /* Flip all the bits on. */
12256 desc[i].mask = target_flags;
12257 if (desc[i].code == end)
12263 spe_init_builtins (void)
12265 tree puint_type_node = build_pointer_type (unsigned_type_node);
12266 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12267 struct builtin_description *d;
12270 tree v2si_ftype_4_v2si
12271 = build_function_type_list (opaque_V2SI_type_node,
12272 opaque_V2SI_type_node,
12273 opaque_V2SI_type_node,
12274 opaque_V2SI_type_node,
12275 opaque_V2SI_type_node,
12278 tree v2sf_ftype_4_v2sf
12279 = build_function_type_list (opaque_V2SF_type_node,
12280 opaque_V2SF_type_node,
12281 opaque_V2SF_type_node,
12282 opaque_V2SF_type_node,
12283 opaque_V2SF_type_node,
12286 tree int_ftype_int_v2si_v2si
12287 = build_function_type_list (integer_type_node,
12289 opaque_V2SI_type_node,
12290 opaque_V2SI_type_node,
12293 tree int_ftype_int_v2sf_v2sf
12294 = build_function_type_list (integer_type_node,
12296 opaque_V2SF_type_node,
12297 opaque_V2SF_type_node,
12300 tree void_ftype_v2si_puint_int
12301 = build_function_type_list (void_type_node,
12302 opaque_V2SI_type_node,
12307 tree void_ftype_v2si_puint_char
12308 = build_function_type_list (void_type_node,
12309 opaque_V2SI_type_node,
12314 tree void_ftype_v2si_pv2si_int
12315 = build_function_type_list (void_type_node,
12316 opaque_V2SI_type_node,
12317 opaque_p_V2SI_type_node,
12321 tree void_ftype_v2si_pv2si_char
12322 = build_function_type_list (void_type_node,
12323 opaque_V2SI_type_node,
12324 opaque_p_V2SI_type_node,
12328 tree void_ftype_int
12329 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12331 tree int_ftype_void
12332 = build_function_type_list (integer_type_node, NULL_TREE);
12334 tree v2si_ftype_pv2si_int
12335 = build_function_type_list (opaque_V2SI_type_node,
12336 opaque_p_V2SI_type_node,
12340 tree v2si_ftype_puint_int
12341 = build_function_type_list (opaque_V2SI_type_node,
12346 tree v2si_ftype_pushort_int
12347 = build_function_type_list (opaque_V2SI_type_node,
12352 tree v2si_ftype_signed_char
12353 = build_function_type_list (opaque_V2SI_type_node,
12354 signed_char_type_node,
12357 /* The initialization of the simple binary and unary builtins is
12358 done in rs6000_common_init_builtins, but we have to enable the
12359 mask bits here manually because we have run out of `target_flags'
12360 bits. We really need to redesign this mask business. */
12362 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12363 ARRAY_SIZE (bdesc_2arg),
12364 SPE_BUILTIN_EVADDW,
12365 SPE_BUILTIN_EVXOR);
12366 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12367 ARRAY_SIZE (bdesc_1arg),
12369 SPE_BUILTIN_EVSUBFUSIAAW);
12370 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12371 ARRAY_SIZE (bdesc_spe_predicates),
12372 SPE_BUILTIN_EVCMPEQ,
12373 SPE_BUILTIN_EVFSTSTLT);
12374 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12375 ARRAY_SIZE (bdesc_spe_evsel),
12376 SPE_BUILTIN_EVSEL_CMPGTS,
12377 SPE_BUILTIN_EVSEL_FSTSTEQ);
12379 (*lang_hooks.decls.pushdecl)
12380 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12381 get_identifier ("__ev64_opaque__"),
12382 opaque_V2SI_type_node));
12384 /* Initialize irregular SPE builtins. */
12386 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12387 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12388 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12389 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12390 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12391 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12392 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12393 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12394 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12395 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12396 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12397 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12398 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12399 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12400 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12401 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12402 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12403 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12406 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12407 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12408 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12409 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12410 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12411 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12412 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12413 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12414 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12415 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12416 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12417 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12418 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12419 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12420 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12421 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12422 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12423 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12424 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12425 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12426 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12427 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12430 d = (struct builtin_description *) bdesc_spe_predicates;
12431 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12435 switch (insn_data[d->icode].operand[1].mode)
12438 type = int_ftype_int_v2si_v2si;
12441 type = int_ftype_int_v2sf_v2sf;
12444 gcc_unreachable ();
12447 def_builtin (d->mask, d->name, type, d->code);
12450 /* Evsel predicates. */
12451 d = (struct builtin_description *) bdesc_spe_evsel;
12452 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12456 switch (insn_data[d->icode].operand[1].mode)
12459 type = v2si_ftype_4_v2si;
12462 type = v2sf_ftype_4_v2sf;
12465 gcc_unreachable ();
12468 def_builtin (d->mask, d->name, type, d->code);
12473 paired_init_builtins (void)
12475 const struct builtin_description *d;
12478 tree int_ftype_int_v2sf_v2sf
12479 = build_function_type_list (integer_type_node,
12484 tree pcfloat_type_node =
12485 build_pointer_type (build_qualified_type
12486 (float_type_node, TYPE_QUAL_CONST));
12488 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12489 long_integer_type_node,
12492 tree void_ftype_v2sf_long_pcfloat =
12493 build_function_type_list (void_type_node,
12495 long_integer_type_node,
12500 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12501 PAIRED_BUILTIN_LX);
12504 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12505 PAIRED_BUILTIN_STX);
12508 d = bdesc_paired_preds;
12509 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12513 switch (insn_data[d->icode].operand[1].mode)
12516 type = int_ftype_int_v2sf_v2sf;
12519 gcc_unreachable ();
12522 def_builtin (d->mask, d->name, type, d->code);
12527 altivec_init_builtins (void)
12529 const struct builtin_description *d;
12530 const struct builtin_description_predicates *dp;
12534 tree pvoid_type_node = build_pointer_type (void_type_node);
12536 tree pcvoid_type_node
12537 = build_pointer_type (build_qualified_type (void_type_node,
12540 tree int_ftype_opaque
12541 = build_function_type_list (integer_type_node,
12542 opaque_V4SI_type_node, NULL_TREE);
12543 tree opaque_ftype_opaque
12544 = build_function_type_list (integer_type_node, NULL_TREE);
12545 tree opaque_ftype_opaque_int
12546 = build_function_type_list (opaque_V4SI_type_node,
12547 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12548 tree opaque_ftype_opaque_opaque_int
12549 = build_function_type_list (opaque_V4SI_type_node,
12550 opaque_V4SI_type_node, opaque_V4SI_type_node,
12551 integer_type_node, NULL_TREE);
12552 tree int_ftype_int_opaque_opaque
12553 = build_function_type_list (integer_type_node,
12554 integer_type_node, opaque_V4SI_type_node,
12555 opaque_V4SI_type_node, NULL_TREE);
12556 tree int_ftype_int_v4si_v4si
12557 = build_function_type_list (integer_type_node,
12558 integer_type_node, V4SI_type_node,
12559 V4SI_type_node, NULL_TREE);
12560 tree void_ftype_v4si
12561 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12562 tree v8hi_ftype_void
12563 = build_function_type_list (V8HI_type_node, NULL_TREE);
12564 tree void_ftype_void
12565 = build_function_type_list (void_type_node, NULL_TREE);
12566 tree void_ftype_int
12567 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12569 tree opaque_ftype_long_pcvoid
12570 = build_function_type_list (opaque_V4SI_type_node,
12571 long_integer_type_node, pcvoid_type_node,
12573 tree v16qi_ftype_long_pcvoid
12574 = build_function_type_list (V16QI_type_node,
12575 long_integer_type_node, pcvoid_type_node,
12577 tree v8hi_ftype_long_pcvoid
12578 = build_function_type_list (V8HI_type_node,
12579 long_integer_type_node, pcvoid_type_node,
12581 tree v4si_ftype_long_pcvoid
12582 = build_function_type_list (V4SI_type_node,
12583 long_integer_type_node, pcvoid_type_node,
12585 tree v4sf_ftype_long_pcvoid
12586 = build_function_type_list (V4SF_type_node,
12587 long_integer_type_node, pcvoid_type_node,
12589 tree v2df_ftype_long_pcvoid
12590 = build_function_type_list (V2DF_type_node,
12591 long_integer_type_node, pcvoid_type_node,
12593 tree v2di_ftype_long_pcvoid
12594 = build_function_type_list (V2DI_type_node,
12595 long_integer_type_node, pcvoid_type_node,
12598 tree void_ftype_opaque_long_pvoid
12599 = build_function_type_list (void_type_node,
12600 opaque_V4SI_type_node, long_integer_type_node,
12601 pvoid_type_node, NULL_TREE);
12602 tree void_ftype_v4si_long_pvoid
12603 = build_function_type_list (void_type_node,
12604 V4SI_type_node, long_integer_type_node,
12605 pvoid_type_node, NULL_TREE);
12606 tree void_ftype_v16qi_long_pvoid
12607 = build_function_type_list (void_type_node,
12608 V16QI_type_node, long_integer_type_node,
12609 pvoid_type_node, NULL_TREE);
12610 tree void_ftype_v8hi_long_pvoid
12611 = build_function_type_list (void_type_node,
12612 V8HI_type_node, long_integer_type_node,
12613 pvoid_type_node, NULL_TREE);
12614 tree void_ftype_v4sf_long_pvoid
12615 = build_function_type_list (void_type_node,
12616 V4SF_type_node, long_integer_type_node,
12617 pvoid_type_node, NULL_TREE);
12618 tree void_ftype_v2df_long_pvoid
12619 = build_function_type_list (void_type_node,
12620 V2DF_type_node, long_integer_type_node,
12621 pvoid_type_node, NULL_TREE);
12622 tree void_ftype_v2di_long_pvoid
12623 = build_function_type_list (void_type_node,
12624 V2DI_type_node, long_integer_type_node,
12625 pvoid_type_node, NULL_TREE);
12626 tree int_ftype_int_v8hi_v8hi
12627 = build_function_type_list (integer_type_node,
12628 integer_type_node, V8HI_type_node,
12629 V8HI_type_node, NULL_TREE);
12630 tree int_ftype_int_v16qi_v16qi
12631 = build_function_type_list (integer_type_node,
12632 integer_type_node, V16QI_type_node,
12633 V16QI_type_node, NULL_TREE);
12634 tree int_ftype_int_v4sf_v4sf
12635 = build_function_type_list (integer_type_node,
12636 integer_type_node, V4SF_type_node,
12637 V4SF_type_node, NULL_TREE);
12638 tree int_ftype_int_v2df_v2df
12639 = build_function_type_list (integer_type_node,
12640 integer_type_node, V2DF_type_node,
12641 V2DF_type_node, NULL_TREE);
12642 tree v4si_ftype_v4si
12643 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12644 tree v8hi_ftype_v8hi
12645 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12646 tree v16qi_ftype_v16qi
12647 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12648 tree v4sf_ftype_v4sf
12649 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12650 tree v2df_ftype_v2df
12651 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12652 tree void_ftype_pcvoid_int_int
12653 = build_function_type_list (void_type_node,
12654 pcvoid_type_node, integer_type_node,
12655 integer_type_node, NULL_TREE);
12657 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12658 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12659 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12660 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12661 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12662 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12663 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12664 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12666 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12668 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12669 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12670 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12671 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12672 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12673 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12674 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12675 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12676 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12677 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12678 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12679 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12680 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12681 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12683 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12684 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12685 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12686 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12688 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12689 VSX_BUILTIN_LXVD2X_V2DF);
12690 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12691 VSX_BUILTIN_LXVD2X_V2DI);
12692 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12693 VSX_BUILTIN_LXVW4X_V4SF);
12694 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12695 VSX_BUILTIN_LXVW4X_V4SI);
12696 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12697 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12698 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12699 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12700 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12701 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12702 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12703 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12704 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12705 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12706 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12707 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12708 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12709 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12710 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12711 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
12712 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
12713 VSX_BUILTIN_VEC_LD);
12714 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
12715 VSX_BUILTIN_VEC_ST);
12717 if (rs6000_cpu == PROCESSOR_CELL)
12719 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12720 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12721 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12722 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12724 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12725 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12726 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12727 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12729 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12730 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12731 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12732 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12734 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12735 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12736 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12737 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12739 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12740 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12741 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12743 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12744 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12745 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12746 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12747 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12748 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12749 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12750 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12751 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12752 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12753 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12754 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12756 /* Add the DST variants. */
12758 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12759 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12761 /* Initialize the predicates. */
12762 dp = bdesc_altivec_preds;
12763 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12765 enum machine_mode mode1;
12767 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12768 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12769 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12770 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12775 mode1 = insn_data[dp->icode].operand[1].mode;
12780 type = int_ftype_int_opaque_opaque;
12783 type = int_ftype_int_v4si_v4si;
12786 type = int_ftype_int_v8hi_v8hi;
12789 type = int_ftype_int_v16qi_v16qi;
12792 type = int_ftype_int_v4sf_v4sf;
12795 type = int_ftype_int_v2df_v2df;
12798 gcc_unreachable ();
12801 def_builtin (dp->mask, dp->name, type, dp->code);
12804 /* Initialize the abs* operators. */
12806 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12808 enum machine_mode mode0;
12811 mode0 = insn_data[d->icode].operand[0].mode;
12816 type = v4si_ftype_v4si;
12819 type = v8hi_ftype_v8hi;
12822 type = v16qi_ftype_v16qi;
12825 type = v4sf_ftype_v4sf;
12828 type = v2df_ftype_v2df;
12831 gcc_unreachable ();
12834 def_builtin (d->mask, d->name, type, d->code);
12837 if (TARGET_ALTIVEC)
12841 /* Initialize target builtin that implements
12842 targetm.vectorize.builtin_mask_for_load. */
12844 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12845 v16qi_ftype_long_pcvoid,
12846 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12847 BUILT_IN_MD, NULL, NULL_TREE);
12848 TREE_READONLY (decl) = 1;
12849 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12850 altivec_builtin_mask_for_load = decl;
12853 /* Access to the vec_init patterns. */
12854 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12855 integer_type_node, integer_type_node,
12856 integer_type_node, NULL_TREE);
12857 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12858 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12860 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12861 short_integer_type_node,
12862 short_integer_type_node,
12863 short_integer_type_node,
12864 short_integer_type_node,
12865 short_integer_type_node,
12866 short_integer_type_node,
12867 short_integer_type_node, NULL_TREE);
12868 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12869 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12871 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12872 char_type_node, char_type_node,
12873 char_type_node, char_type_node,
12874 char_type_node, char_type_node,
12875 char_type_node, char_type_node,
12876 char_type_node, char_type_node,
12877 char_type_node, char_type_node,
12878 char_type_node, char_type_node,
12879 char_type_node, NULL_TREE);
12880 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12881 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12883 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12884 float_type_node, float_type_node,
12885 float_type_node, NULL_TREE);
12886 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12887 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12891 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12892 double_type_node, NULL_TREE);
12893 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12894 VSX_BUILTIN_VEC_INIT_V2DF);
12896 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12897 intDI_type_node, NULL_TREE);
12898 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12899 VSX_BUILTIN_VEC_INIT_V2DI);
12902 /* Access to the vec_set patterns. */
12903 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12905 integer_type_node, NULL_TREE);
12906 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12907 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12909 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12911 integer_type_node, NULL_TREE);
12912 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12913 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12915 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12917 integer_type_node, NULL_TREE);
12918 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12919 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12921 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12923 integer_type_node, NULL_TREE);
12924 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12925 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12929 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12931 integer_type_node, NULL_TREE);
12932 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12933 VSX_BUILTIN_VEC_SET_V2DF);
12935 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12937 integer_type_node, NULL_TREE);
12938 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12939 VSX_BUILTIN_VEC_SET_V2DI);
12942 /* Access to the vec_extract patterns. */
12943 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12944 integer_type_node, NULL_TREE);
12945 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12946 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12948 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12949 integer_type_node, NULL_TREE);
12950 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12951 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12953 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12954 integer_type_node, NULL_TREE);
12955 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12956 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12958 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12959 integer_type_node, NULL_TREE);
12960 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12961 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12965 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12966 integer_type_node, NULL_TREE);
12967 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12968 VSX_BUILTIN_VEC_EXT_V2DF);
12970 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12971 integer_type_node, NULL_TREE);
12972 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12973 VSX_BUILTIN_VEC_EXT_V2DI);
12977 /* Hash function for builtin functions with up to 3 arguments and a return
12980 builtin_hash_function (const void *hash_entry)
12984 const struct builtin_hash_struct *bh =
12985 (const struct builtin_hash_struct *) hash_entry;
12987 for (i = 0; i < 4; i++)
12989 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12990 ret = (ret * 2) + bh->uns_p[i];
12996 /* Compare builtin hash entries H1 and H2 for equivalence. */
12998 builtin_hash_eq (const void *h1, const void *h2)
13000 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13001 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13003 return ((p1->mode[0] == p2->mode[0])
13004 && (p1->mode[1] == p2->mode[1])
13005 && (p1->mode[2] == p2->mode[2])
13006 && (p1->mode[3] == p2->mode[3])
13007 && (p1->uns_p[0] == p2->uns_p[0])
13008 && (p1->uns_p[1] == p2->uns_p[1])
13009 && (p1->uns_p[2] == p2->uns_p[2])
13010 && (p1->uns_p[3] == p2->uns_p[3]));
13013 /* Map types for builtin functions with an explicit return type and up to 3
13014 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13015 of the argument. */
13017 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13018 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13019 enum rs6000_builtins builtin, const char *name)
13021 struct builtin_hash_struct h;
13022 struct builtin_hash_struct *h2;
13026 tree ret_type = NULL_TREE;
13027 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13029 /* Create builtin_hash_table. */
13030 if (builtin_hash_table == NULL)
13031 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13032 builtin_hash_eq, NULL);
13034 h.type = NULL_TREE;
13035 h.mode[0] = mode_ret;
13036 h.mode[1] = mode_arg0;
13037 h.mode[2] = mode_arg1;
13038 h.mode[3] = mode_arg2;
13044 /* If the builtin is a type that produces unsigned results or takes unsigned
13045 arguments, and it is returned as a decl for the vectorizer (such as
13046 widening multiplies, permute), make sure the arguments and return value
13047 are type correct. */
13050 /* unsigned 2 argument functions. */
13051 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13052 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13053 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13054 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13060 /* unsigned 3 argument functions. */
13061 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13062 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13063 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13064 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13065 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13066 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13067 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13068 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13069 case VSX_BUILTIN_VPERM_16QI_UNS:
13070 case VSX_BUILTIN_VPERM_8HI_UNS:
13071 case VSX_BUILTIN_VPERM_4SI_UNS:
13072 case VSX_BUILTIN_VPERM_2DI_UNS:
13073 case VSX_BUILTIN_XXSEL_16QI_UNS:
13074 case VSX_BUILTIN_XXSEL_8HI_UNS:
13075 case VSX_BUILTIN_XXSEL_4SI_UNS:
13076 case VSX_BUILTIN_XXSEL_2DI_UNS:
13083 /* signed permute functions with unsigned char mask. */
13084 case ALTIVEC_BUILTIN_VPERM_16QI:
13085 case ALTIVEC_BUILTIN_VPERM_8HI:
13086 case ALTIVEC_BUILTIN_VPERM_4SI:
13087 case ALTIVEC_BUILTIN_VPERM_4SF:
13088 case ALTIVEC_BUILTIN_VPERM_2DI:
13089 case ALTIVEC_BUILTIN_VPERM_2DF:
13090 case VSX_BUILTIN_VPERM_16QI:
13091 case VSX_BUILTIN_VPERM_8HI:
13092 case VSX_BUILTIN_VPERM_4SI:
13093 case VSX_BUILTIN_VPERM_4SF:
13094 case VSX_BUILTIN_VPERM_2DI:
13095 case VSX_BUILTIN_VPERM_2DF:
13099 /* unsigned args, signed return. */
13100 case VSX_BUILTIN_XVCVUXDDP_UNS:
13101 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13105 /* signed args, unsigned return. */
13106 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13107 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13115 /* Figure out how many args are present. */
13116 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13120 fatal_error ("internal error: builtin function %s had no type", name);
13122 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13123 if (!ret_type && h.uns_p[0])
13124 ret_type = builtin_mode_to_type[h.mode[0]][0];
13127 fatal_error ("internal error: builtin function %s had an unexpected "
13128 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13130 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13131 arg_type[i] = NULL_TREE;
13133 for (i = 0; i < num_args; i++)
13135 int m = (int) h.mode[i+1];
13136 int uns_p = h.uns_p[i+1];
13138 arg_type[i] = builtin_mode_to_type[m][uns_p];
13139 if (!arg_type[i] && uns_p)
13140 arg_type[i] = builtin_mode_to_type[m][0];
13143 fatal_error ("internal error: builtin function %s, argument %d "
13144 "had unexpected argument type %s", name, i,
13145 GET_MODE_NAME (m));
13148 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13149 if (*found == NULL)
13151 h2 = ggc_alloc_builtin_hash_struct ();
13153 *found = (void *)h2;
13155 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13156 arg_type[2], NULL_TREE);
13159 return ((struct builtin_hash_struct *)(*found))->type;
13163 rs6000_common_init_builtins (void)
13165 const struct builtin_description *d;
13168 tree opaque_ftype_opaque = NULL_TREE;
13169 tree opaque_ftype_opaque_opaque = NULL_TREE;
13170 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13171 tree v2si_ftype_qi = NULL_TREE;
13172 tree v2si_ftype_v2si_qi = NULL_TREE;
13173 tree v2si_ftype_int_qi = NULL_TREE;
13175 if (!TARGET_PAIRED_FLOAT)
13177 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13178 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13181 /* Add the ternary operators. */
13183 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13186 int mask = d->mask;
13188 if ((mask != 0 && (mask & target_flags) == 0)
13189 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13192 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13193 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13194 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13195 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13197 if (! (type = opaque_ftype_opaque_opaque_opaque))
13198 type = opaque_ftype_opaque_opaque_opaque
13199 = build_function_type_list (opaque_V4SI_type_node,
13200 opaque_V4SI_type_node,
13201 opaque_V4SI_type_node,
13202 opaque_V4SI_type_node,
13207 enum insn_code icode = d->icode;
13208 if (d->name == 0 || icode == CODE_FOR_nothing)
13211 type = builtin_function_type (insn_data[icode].operand[0].mode,
13212 insn_data[icode].operand[1].mode,
13213 insn_data[icode].operand[2].mode,
13214 insn_data[icode].operand[3].mode,
13218 def_builtin (d->mask, d->name, type, d->code);
13221 /* Add the binary operators. */
13223 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13225 enum machine_mode mode0, mode1, mode2;
13227 int mask = d->mask;
13229 if ((mask != 0 && (mask & target_flags) == 0)
13230 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13233 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13234 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13235 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13236 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13238 if (! (type = opaque_ftype_opaque_opaque))
13239 type = opaque_ftype_opaque_opaque
13240 = build_function_type_list (opaque_V4SI_type_node,
13241 opaque_V4SI_type_node,
13242 opaque_V4SI_type_node,
13247 enum insn_code icode = d->icode;
13248 if (d->name == 0 || icode == CODE_FOR_nothing)
13251 mode0 = insn_data[icode].operand[0].mode;
13252 mode1 = insn_data[icode].operand[1].mode;
13253 mode2 = insn_data[icode].operand[2].mode;
13255 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13257 if (! (type = v2si_ftype_v2si_qi))
13258 type = v2si_ftype_v2si_qi
13259 = build_function_type_list (opaque_V2SI_type_node,
13260 opaque_V2SI_type_node,
13265 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13266 && mode2 == QImode)
13268 if (! (type = v2si_ftype_int_qi))
13269 type = v2si_ftype_int_qi
13270 = build_function_type_list (opaque_V2SI_type_node,
13277 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13281 def_builtin (d->mask, d->name, type, d->code);
13284 /* Add the simple unary operators. */
13285 d = (struct builtin_description *) bdesc_1arg;
13286 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13288 enum machine_mode mode0, mode1;
13290 int mask = d->mask;
13292 if ((mask != 0 && (mask & target_flags) == 0)
13293 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13296 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13297 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13298 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13299 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13301 if (! (type = opaque_ftype_opaque))
13302 type = opaque_ftype_opaque
13303 = build_function_type_list (opaque_V4SI_type_node,
13304 opaque_V4SI_type_node,
13309 enum insn_code icode = d->icode;
13310 if (d->name == 0 || icode == CODE_FOR_nothing)
13313 mode0 = insn_data[icode].operand[0].mode;
13314 mode1 = insn_data[icode].operand[1].mode;
13316 if (mode0 == V2SImode && mode1 == QImode)
13318 if (! (type = v2si_ftype_qi))
13319 type = v2si_ftype_qi
13320 = build_function_type_list (opaque_V2SI_type_node,
13326 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13330 def_builtin (d->mask, d->name, type, d->code);
13335 rs6000_init_libfuncs (void)
13337 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13338 && !TARGET_POWER2 && !TARGET_POWERPC)
13340 /* AIX library routines for float->int conversion. */
13341 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13342 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13343 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13344 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13347 if (!TARGET_IEEEQUAD)
13348 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13349 if (!TARGET_XL_COMPAT)
13351 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13352 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13353 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13354 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13356 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13358 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13359 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13360 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13361 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13362 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13363 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13364 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13366 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13367 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13368 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13369 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13370 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13371 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13372 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13373 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13376 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13377 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13381 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13382 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13383 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13384 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13388 /* 32-bit SVR4 quad floating point routines. */
13390 set_optab_libfunc (add_optab, TFmode, "_q_add");
13391 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13392 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13393 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13394 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13395 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13396 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13398 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13399 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13400 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13401 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13402 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13403 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13405 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13406 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13407 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13408 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13409 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13410 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13411 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13412 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13417 /* Expand a block clear operation, and return 1 if successful. Return 0
13418 if we should let the compiler generate normal code.
13420 operands[0] is the destination
13421 operands[1] is the length
13422 operands[3] is the alignment */
13425 expand_block_clear (rtx operands[])
13427 rtx orig_dest = operands[0];
13428 rtx bytes_rtx = operands[1];
13429 rtx align_rtx = operands[3];
13430 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13431 HOST_WIDE_INT align;
13432 HOST_WIDE_INT bytes;
13437 /* If this is not a fixed size move, just call memcpy */
13441 /* This must be a fixed size alignment */
13442 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13443 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13445 /* Anything to clear? */
13446 bytes = INTVAL (bytes_rtx);
13450 /* Use the builtin memset after a point, to avoid huge code bloat.
13451 When optimize_size, avoid any significant code bloat; calling
13452 memset is about 4 instructions, so allow for one instruction to
13453 load zero and three to do clearing. */
13454 if (TARGET_ALTIVEC && align >= 128)
13456 else if (TARGET_POWERPC64 && align >= 32)
13458 else if (TARGET_SPE && align >= 64)
13463 if (optimize_size && bytes > 3 * clear_step)
13465 if (! optimize_size && bytes > 8 * clear_step)
13468 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13470 enum machine_mode mode = BLKmode;
13473 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13478 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13483 else if (bytes >= 8 && TARGET_POWERPC64
13484 /* 64-bit loads and stores require word-aligned
13486 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13491 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13492 { /* move 4 bytes */
13496 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13497 { /* move 2 bytes */
13501 else /* move 1 byte at a time */
13507 dest = adjust_address (orig_dest, mode, offset);
13509 emit_move_insn (dest, CONST0_RTX (mode));
13516 /* Expand a block move operation, and return 1 if successful. Return 0
13517 if we should let the compiler generate normal code.
13519 operands[0] is the destination
13520 operands[1] is the source
13521 operands[2] is the length
13522 operands[3] is the alignment */
13524 #define MAX_MOVE_REG 4
13527 expand_block_move (rtx operands[])
13529 rtx orig_dest = operands[0];
13530 rtx orig_src = operands[1];
13531 rtx bytes_rtx = operands[2];
13532 rtx align_rtx = operands[3];
13533 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13538 rtx stores[MAX_MOVE_REG];
13541 /* If this is not a fixed size move, just call memcpy */
13545 /* This must be a fixed size alignment */
13546 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13547 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13549 /* Anything to move? */
13550 bytes = INTVAL (bytes_rtx);
13554 if (bytes > rs6000_block_move_inline_limit)
13557 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13560 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13561 rtx (*mov) (rtx, rtx);
13563 enum machine_mode mode = BLKmode;
13566 /* Altivec first, since it will be faster than a string move
13567 when it applies, and usually not significantly larger. */
13568 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13572 gen_func.mov = gen_movv4si;
13574 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13578 gen_func.mov = gen_movv2si;
13580 else if (TARGET_STRING
13581 && bytes > 24 /* move up to 32 bytes at a time */
13587 && ! fixed_regs[10]
13588 && ! fixed_regs[11]
13589 && ! fixed_regs[12])
13591 move_bytes = (bytes > 32) ? 32 : bytes;
13592 gen_func.movmemsi = gen_movmemsi_8reg;
13594 else if (TARGET_STRING
13595 && bytes > 16 /* move up to 24 bytes at a time */
13601 && ! fixed_regs[10])
13603 move_bytes = (bytes > 24) ? 24 : bytes;
13604 gen_func.movmemsi = gen_movmemsi_6reg;
13606 else if (TARGET_STRING
13607 && bytes > 8 /* move up to 16 bytes at a time */
13611 && ! fixed_regs[8])
13613 move_bytes = (bytes > 16) ? 16 : bytes;
13614 gen_func.movmemsi = gen_movmemsi_4reg;
13616 else if (bytes >= 8 && TARGET_POWERPC64
13617 /* 64-bit loads and stores require word-aligned
13619 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13623 gen_func.mov = gen_movdi;
13625 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13626 { /* move up to 8 bytes at a time */
13627 move_bytes = (bytes > 8) ? 8 : bytes;
13628 gen_func.movmemsi = gen_movmemsi_2reg;
13630 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13631 { /* move 4 bytes */
13634 gen_func.mov = gen_movsi;
13636 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13637 { /* move 2 bytes */
13640 gen_func.mov = gen_movhi;
13642 else if (TARGET_STRING && bytes > 1)
13643 { /* move up to 4 bytes at a time */
13644 move_bytes = (bytes > 4) ? 4 : bytes;
13645 gen_func.movmemsi = gen_movmemsi_1reg;
13647 else /* move 1 byte at a time */
13651 gen_func.mov = gen_movqi;
13654 src = adjust_address (orig_src, mode, offset);
13655 dest = adjust_address (orig_dest, mode, offset);
13657 if (mode != BLKmode)
13659 rtx tmp_reg = gen_reg_rtx (mode);
13661 emit_insn ((*gen_func.mov) (tmp_reg, src));
13662 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13665 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13668 for (i = 0; i < num_reg; i++)
13669 emit_insn (stores[i]);
13673 if (mode == BLKmode)
13675 /* Move the address into scratch registers. The movmemsi
13676 patterns require zero offset. */
13677 if (!REG_P (XEXP (src, 0)))
13679 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13680 src = replace_equiv_address (src, src_reg);
13682 set_mem_size (src, move_bytes);
13684 if (!REG_P (XEXP (dest, 0)))
13686 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13687 dest = replace_equiv_address (dest, dest_reg);
13689 set_mem_size (dest, move_bytes);
13691 emit_insn ((*gen_func.movmemsi) (dest, src,
13692 GEN_INT (move_bytes & 31),
13701 /* Return a string to perform a load_multiple operation.
13702 operands[0] is the vector.
13703 operands[1] is the source address.
13704 operands[2] is the first destination register. */
13707 rs6000_output_load_multiple (rtx operands[3])
13709 /* We have to handle the case where the pseudo used to contain the address
13710 is assigned to one of the output registers. */
13712 int words = XVECLEN (operands[0], 0);
13715 if (XVECLEN (operands[0], 0) == 1)
13716 return "{l|lwz} %2,0(%1)";
13718 for (i = 0; i < words; i++)
13719 if (refers_to_regno_p (REGNO (operands[2]) + i,
13720 REGNO (operands[2]) + i + 1, operands[1], 0))
13724 xop[0] = GEN_INT (4 * (words-1));
13725 xop[1] = operands[1];
13726 xop[2] = operands[2];
13727 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13732 xop[0] = GEN_INT (4 * (words-1));
13733 xop[1] = operands[1];
13734 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13735 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);
13740 for (j = 0; j < words; j++)
13743 xop[0] = GEN_INT (j * 4);
13744 xop[1] = operands[1];
13745 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13746 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13748 xop[0] = GEN_INT (i * 4);
13749 xop[1] = operands[1];
13750 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13755 return "{lsi|lswi} %2,%1,%N0";
13759 /* A validation routine: say whether CODE, a condition code, and MODE
13760 match. The other alternatives either don't make sense or should
13761 never be generated. */
13764 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13766 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13767 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13768 && GET_MODE_CLASS (mode) == MODE_CC);
13770 /* These don't make sense. */
13771 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13772 || mode != CCUNSmode);
13774 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13775 || mode == CCUNSmode);
13777 gcc_assert (mode == CCFPmode
13778 || (code != ORDERED && code != UNORDERED
13779 && code != UNEQ && code != LTGT
13780 && code != UNGT && code != UNLT
13781 && code != UNGE && code != UNLE));
13783 /* These should never be generated except for
13784 flag_finite_math_only. */
13785 gcc_assert (mode != CCFPmode
13786 || flag_finite_math_only
13787 || (code != LE && code != GE
13788 && code != UNEQ && code != LTGT
13789 && code != UNGT && code != UNLT));
13791 /* These are invalid; the information is not there. */
13792 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13796 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13797 mask required to convert the result of a rotate insn into a shift
13798 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13801 includes_lshift_p (rtx shiftop, rtx andop)
13803 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13805 shift_mask <<= INTVAL (shiftop);
13807 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13810 /* Similar, but for right shift. */
13813 includes_rshift_p (rtx shiftop, rtx andop)
13815 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13817 shift_mask >>= INTVAL (shiftop);
13819 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13822 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13823 to perform a left shift. It must have exactly SHIFTOP least
13824 significant 0's, then one or more 1's, then zero or more 0's. */
13827 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13829 if (GET_CODE (andop) == CONST_INT)
13831 HOST_WIDE_INT c, lsb, shift_mask;
13833 c = INTVAL (andop);
13834 if (c == 0 || c == ~0)
13838 shift_mask <<= INTVAL (shiftop);
13840 /* Find the least significant one bit. */
13843 /* It must coincide with the LSB of the shift mask. */
13844 if (-lsb != shift_mask)
13847 /* Invert to look for the next transition (if any). */
13850 /* Remove the low group of ones (originally low group of zeros). */
13853 /* Again find the lsb, and check we have all 1's above. */
13857 else if (GET_CODE (andop) == CONST_DOUBLE
13858 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13860 HOST_WIDE_INT low, high, lsb;
13861 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13863 low = CONST_DOUBLE_LOW (andop);
13864 if (HOST_BITS_PER_WIDE_INT < 64)
13865 high = CONST_DOUBLE_HIGH (andop);
13867 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13868 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13871 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13873 shift_mask_high = ~0;
13874 if (INTVAL (shiftop) > 32)
13875 shift_mask_high <<= INTVAL (shiftop) - 32;
13877 lsb = high & -high;
13879 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13885 lsb = high & -high;
13886 return high == -lsb;
13889 shift_mask_low = ~0;
13890 shift_mask_low <<= INTVAL (shiftop);
13894 if (-lsb != shift_mask_low)
13897 if (HOST_BITS_PER_WIDE_INT < 64)
13902 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13904 lsb = high & -high;
13905 return high == -lsb;
13909 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13915 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13916 to perform a left shift. It must have SHIFTOP or more least
13917 significant 0's, with the remainder of the word 1's. */
13920 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13922 if (GET_CODE (andop) == CONST_INT)
13924 HOST_WIDE_INT c, lsb, shift_mask;
13927 shift_mask <<= INTVAL (shiftop);
13928 c = INTVAL (andop);
13930 /* Find the least significant one bit. */
13933 /* It must be covered by the shift mask.
13934 This test also rejects c == 0. */
13935 if ((lsb & shift_mask) == 0)
13938 /* Check we have all 1's above the transition, and reject all 1's. */
13939 return c == -lsb && lsb != 1;
13941 else if (GET_CODE (andop) == CONST_DOUBLE
13942 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13944 HOST_WIDE_INT low, lsb, shift_mask_low;
13946 low = CONST_DOUBLE_LOW (andop);
13948 if (HOST_BITS_PER_WIDE_INT < 64)
13950 HOST_WIDE_INT high, shift_mask_high;
13952 high = CONST_DOUBLE_HIGH (andop);
13956 shift_mask_high = ~0;
13957 if (INTVAL (shiftop) > 32)
13958 shift_mask_high <<= INTVAL (shiftop) - 32;
13960 lsb = high & -high;
13962 if ((lsb & shift_mask_high) == 0)
13965 return high == -lsb;
13971 shift_mask_low = ~0;
13972 shift_mask_low <<= INTVAL (shiftop);
13976 if ((lsb & shift_mask_low) == 0)
13979 return low == -lsb && lsb != 1;
13985 /* Return 1 if operands will generate a valid arguments to rlwimi
13986 instruction for insert with right shift in 64-bit mode. The mask may
13987 not start on the first bit or stop on the last bit because wrap-around
13988 effects of instruction do not correspond to semantics of RTL insn. */
13991 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13993 if (INTVAL (startop) > 32
13994 && INTVAL (startop) < 64
13995 && INTVAL (sizeop) > 1
13996 && INTVAL (sizeop) + INTVAL (startop) < 64
13997 && INTVAL (shiftop) > 0
13998 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13999 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14005 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14006 for lfq and stfq insns iff the registers are hard registers. */
14009 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14011 /* We might have been passed a SUBREG. */
14012 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14015 /* We might have been passed non floating point registers. */
14016 if (!FP_REGNO_P (REGNO (reg1))
14017 || !FP_REGNO_P (REGNO (reg2)))
14020 return (REGNO (reg1) == REGNO (reg2) - 1);
14023 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14024 addr1 and addr2 must be in consecutive memory locations
14025 (addr2 == addr1 + 8). */
14028 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14031 unsigned int reg1, reg2;
14032 int offset1, offset2;
14034 /* The mems cannot be volatile. */
14035 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14038 addr1 = XEXP (mem1, 0);
14039 addr2 = XEXP (mem2, 0);
14041 /* Extract an offset (if used) from the first addr. */
14042 if (GET_CODE (addr1) == PLUS)
14044 /* If not a REG, return zero. */
14045 if (GET_CODE (XEXP (addr1, 0)) != REG)
14049 reg1 = REGNO (XEXP (addr1, 0));
14050 /* The offset must be constant! */
14051 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14053 offset1 = INTVAL (XEXP (addr1, 1));
14056 else if (GET_CODE (addr1) != REG)
14060 reg1 = REGNO (addr1);
14061 /* This was a simple (mem (reg)) expression. Offset is 0. */
14065 /* And now for the second addr. */
14066 if (GET_CODE (addr2) == PLUS)
14068 /* If not a REG, return zero. */
14069 if (GET_CODE (XEXP (addr2, 0)) != REG)
14073 reg2 = REGNO (XEXP (addr2, 0));
14074 /* The offset must be constant. */
14075 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14077 offset2 = INTVAL (XEXP (addr2, 1));
14080 else if (GET_CODE (addr2) != REG)
14084 reg2 = REGNO (addr2);
14085 /* This was a simple (mem (reg)) expression. Offset is 0. */
14089 /* Both of these must have the same base register. */
14093 /* The offset for the second addr must be 8 more than the first addr. */
14094 if (offset2 != offset1 + 8)
14097 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14104 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14106 static bool eliminated = false;
14109 if (mode != SDmode)
14110 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14113 rtx mem = cfun->machine->sdmode_stack_slot;
14114 gcc_assert (mem != NULL_RTX);
14118 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14119 cfun->machine->sdmode_stack_slot = mem;
14125 if (TARGET_DEBUG_ADDR)
14127 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14128 GET_MODE_NAME (mode));
14130 fprintf (stderr, "\tNULL_RTX\n");
14139 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14141 /* Don't walk into types. */
14142 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14144 *walk_subtrees = 0;
14148 switch (TREE_CODE (*tp))
14157 case VIEW_CONVERT_EXPR:
14158 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14168 enum reload_reg_type {
14170 VECTOR_REGISTER_TYPE,
14171 OTHER_REGISTER_TYPE
14174 static enum reload_reg_type
14175 rs6000_reload_register_type (enum reg_class rclass)
14181 return GPR_REGISTER_TYPE;
14186 return VECTOR_REGISTER_TYPE;
14189 return OTHER_REGISTER_TYPE;
14193 /* Inform reload about cases where moving X with a mode MODE to a register in
14194 RCLASS requires an extra scratch or immediate register. Return the class
14195 needed for the immediate register.
14197 For VSX and Altivec, we may need a register to convert sp+offset into
14200 For misaligned 64-bit gpr loads and stores we need a register to
14201 convert an offset address to indirect. */
14204 rs6000_secondary_reload (bool in_p,
14206 reg_class_t rclass_i,
14207 enum machine_mode mode,
14208 secondary_reload_info *sri)
14210 enum reg_class rclass = (enum reg_class) rclass_i;
14211 reg_class_t ret = ALL_REGS;
14212 enum insn_code icode;
14213 bool default_p = false;
14215 sri->icode = CODE_FOR_nothing;
14217 /* Convert vector loads and stores into gprs to use an additional base
14219 icode = rs6000_vector_reload[mode][in_p != false];
14220 if (icode != CODE_FOR_nothing)
14223 sri->icode = CODE_FOR_nothing;
14224 sri->extra_cost = 0;
14226 if (GET_CODE (x) == MEM)
14228 rtx addr = XEXP (x, 0);
14230 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14231 an extra register in that case, but it would need an extra
14232 register if the addressing is reg+reg or (reg+reg)&(-16). */
14233 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14235 if (!legitimate_indirect_address_p (addr, false)
14236 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14238 sri->icode = icode;
14239 /* account for splitting the loads, and converting the
14240 address from reg+reg to reg. */
14241 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14242 + ((GET_CODE (addr) == AND) ? 1 : 0));
14245 /* Loads to and stores from vector registers can only do reg+reg
14246 addressing. Altivec registers can also do (reg+reg)&(-16). */
14247 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14248 || rclass == FLOAT_REGS || rclass == NO_REGS)
14250 if (!VECTOR_MEM_ALTIVEC_P (mode)
14251 && GET_CODE (addr) == AND
14252 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14253 && INTVAL (XEXP (addr, 1)) == -16
14254 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14255 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14257 sri->icode = icode;
14258 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14261 else if (!legitimate_indirect_address_p (addr, false)
14262 && (rclass == NO_REGS
14263 || !legitimate_indexed_address_p (addr, false)))
14265 sri->icode = icode;
14266 sri->extra_cost = 1;
14269 icode = CODE_FOR_nothing;
14271 /* Any other loads, including to pseudo registers which haven't been
14272 assigned to a register yet, default to require a scratch
14276 sri->icode = icode;
14277 sri->extra_cost = 2;
14280 else if (REG_P (x))
14282 int regno = true_regnum (x);
14284 icode = CODE_FOR_nothing;
14285 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14289 enum reg_class xclass = REGNO_REG_CLASS (regno);
14290 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14291 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14293 /* If memory is needed, use default_secondary_reload to create the
14295 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14304 else if (TARGET_POWERPC64
14305 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14307 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14309 rtx addr = XEXP (x, 0);
14311 if (GET_CODE (addr) == PRE_MODIFY)
14312 addr = XEXP (addr, 1);
14313 else if (GET_CODE (addr) == LO_SUM
14314 && GET_CODE (XEXP (addr, 0)) == REG
14315 && GET_CODE (XEXP (addr, 1)) == CONST)
14316 addr = XEXP (XEXP (addr, 1), 0);
14318 if (GET_CODE (addr) == PLUS
14319 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14320 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14323 sri->icode = CODE_FOR_reload_di_load;
14325 sri->icode = CODE_FOR_reload_di_store;
14326 sri->extra_cost = 2;
14336 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14338 gcc_assert (ret != ALL_REGS);
14340 if (TARGET_DEBUG_ADDR)
14343 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14345 reg_class_names[ret],
14346 in_p ? "true" : "false",
14347 reg_class_names[rclass],
14348 GET_MODE_NAME (mode));
14351 fprintf (stderr, ", default secondary reload");
14353 if (sri->icode != CODE_FOR_nothing)
14354 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14355 insn_data[sri->icode].name, sri->extra_cost);
14357 fprintf (stderr, "\n");
14365 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14366 to SP+reg addressing. */
14369 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14371 int regno = true_regnum (reg);
14372 enum machine_mode mode = GET_MODE (reg);
14373 enum reg_class rclass;
14375 rtx and_op2 = NULL_RTX;
14378 rtx scratch_or_premodify = scratch;
14382 if (TARGET_DEBUG_ADDR)
14384 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14385 store_p ? "store" : "load");
14386 fprintf (stderr, "reg:\n");
14388 fprintf (stderr, "mem:\n");
14390 fprintf (stderr, "scratch:\n");
14391 debug_rtx (scratch);
14394 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14395 gcc_assert (GET_CODE (mem) == MEM);
14396 rclass = REGNO_REG_CLASS (regno);
14397 addr = XEXP (mem, 0);
14401 /* GPRs can handle reg + small constant, all other addresses need to use
14402 the scratch register. */
14405 if (GET_CODE (addr) == AND)
14407 and_op2 = XEXP (addr, 1);
14408 addr = XEXP (addr, 0);
14411 if (GET_CODE (addr) == PRE_MODIFY)
14413 scratch_or_premodify = XEXP (addr, 0);
14414 gcc_assert (REG_P (scratch_or_premodify));
14415 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14416 addr = XEXP (addr, 1);
14419 if (GET_CODE (addr) == PLUS
14420 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14421 || and_op2 != NULL_RTX))
14423 addr_op1 = XEXP (addr, 0);
14424 addr_op2 = XEXP (addr, 1);
14425 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14427 if (!REG_P (addr_op2)
14428 && (GET_CODE (addr_op2) != CONST_INT
14429 || !satisfies_constraint_I (addr_op2)))
14431 if (TARGET_DEBUG_ADDR)
14434 "\nMove plus addr to register %s, mode = %s: ",
14435 rs6000_reg_names[REGNO (scratch)],
14436 GET_MODE_NAME (mode));
14437 debug_rtx (addr_op2);
14439 rs6000_emit_move (scratch, addr_op2, Pmode);
14440 addr_op2 = scratch;
14443 emit_insn (gen_rtx_SET (VOIDmode,
14444 scratch_or_premodify,
14445 gen_rtx_PLUS (Pmode,
14449 addr = scratch_or_premodify;
14450 scratch_or_premodify = scratch;
14452 else if (!legitimate_indirect_address_p (addr, false)
14453 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14455 if (TARGET_DEBUG_ADDR)
14457 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14458 rs6000_reg_names[REGNO (scratch_or_premodify)],
14459 GET_MODE_NAME (mode));
14462 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14463 addr = scratch_or_premodify;
14464 scratch_or_premodify = scratch;
14468 /* Float/Altivec registers can only handle reg+reg addressing. Move
14469 other addresses into a scratch register. */
14474 /* With float regs, we need to handle the AND ourselves, since we can't
14475 use the Altivec instruction with an implicit AND -16. Allow scalar
14476 loads to float registers to use reg+offset even if VSX. */
14477 if (GET_CODE (addr) == AND
14478 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14479 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14480 || INTVAL (XEXP (addr, 1)) != -16
14481 || !VECTOR_MEM_ALTIVEC_P (mode)))
14483 and_op2 = XEXP (addr, 1);
14484 addr = XEXP (addr, 0);
14487 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14488 as the address later. */
14489 if (GET_CODE (addr) == PRE_MODIFY
14490 && (!VECTOR_MEM_VSX_P (mode)
14491 || and_op2 != NULL_RTX
14492 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14494 scratch_or_premodify = XEXP (addr, 0);
14495 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14497 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14498 addr = XEXP (addr, 1);
14501 if (legitimate_indirect_address_p (addr, false) /* reg */
14502 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14503 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14504 || (GET_CODE (addr) == AND /* Altivec memory */
14505 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14506 && INTVAL (XEXP (addr, 1)) == -16
14507 && VECTOR_MEM_ALTIVEC_P (mode))
14508 || (rclass == FLOAT_REGS /* legacy float mem */
14509 && GET_MODE_SIZE (mode) == 8
14510 && and_op2 == NULL_RTX
14511 && scratch_or_premodify == scratch
14512 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14515 else if (GET_CODE (addr) == PLUS)
14517 addr_op1 = XEXP (addr, 0);
14518 addr_op2 = XEXP (addr, 1);
14519 gcc_assert (REG_P (addr_op1));
14521 if (TARGET_DEBUG_ADDR)
14523 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14524 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14525 debug_rtx (addr_op2);
14527 rs6000_emit_move (scratch, addr_op2, Pmode);
14528 emit_insn (gen_rtx_SET (VOIDmode,
14529 scratch_or_premodify,
14530 gen_rtx_PLUS (Pmode,
14533 addr = scratch_or_premodify;
14534 scratch_or_premodify = scratch;
14537 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14538 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14540 if (TARGET_DEBUG_ADDR)
14542 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14543 rs6000_reg_names[REGNO (scratch_or_premodify)],
14544 GET_MODE_NAME (mode));
14548 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14549 addr = scratch_or_premodify;
14550 scratch_or_premodify = scratch;
14554 gcc_unreachable ();
14559 gcc_unreachable ();
14562 /* If the original address involved a pre-modify that we couldn't use the VSX
14563 memory instruction with update, and we haven't taken care of already,
14564 store the address in the pre-modify register and use that as the
14566 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14568 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14569 addr = scratch_or_premodify;
14572 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14573 memory instruction, recreate the AND now, including the clobber which is
14574 generated by the general ANDSI3/ANDDI3 patterns for the
14575 andi. instruction. */
14576 if (and_op2 != NULL_RTX)
14578 if (! legitimate_indirect_address_p (addr, false))
14580 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14584 if (TARGET_DEBUG_ADDR)
14586 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14587 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14588 debug_rtx (and_op2);
14591 and_rtx = gen_rtx_SET (VOIDmode,
14593 gen_rtx_AND (Pmode,
14597 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14598 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14599 gen_rtvec (2, and_rtx, cc_clobber)));
14603 /* Adjust the address if it changed. */
14604 if (addr != XEXP (mem, 0))
14606 mem = change_address (mem, mode, addr);
14607 if (TARGET_DEBUG_ADDR)
14608 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14611 /* Now create the move. */
14613 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14615 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14620 /* Convert reloads involving 64-bit gprs and misaligned offset
14621 addressing to use indirect addressing. */
14624 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14626 int regno = true_regnum (reg);
14627 enum reg_class rclass;
14629 rtx scratch_or_premodify = scratch;
14631 if (TARGET_DEBUG_ADDR)
14633 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14634 store_p ? "store" : "load");
14635 fprintf (stderr, "reg:\n");
14637 fprintf (stderr, "mem:\n");
14639 fprintf (stderr, "scratch:\n");
14640 debug_rtx (scratch);
14643 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14644 gcc_assert (GET_CODE (mem) == MEM);
14645 rclass = REGNO_REG_CLASS (regno);
14646 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14647 addr = XEXP (mem, 0);
14649 if (GET_CODE (addr) == PRE_MODIFY)
14651 scratch_or_premodify = XEXP (addr, 0);
14652 gcc_assert (REG_P (scratch_or_premodify));
14653 addr = XEXP (addr, 1);
14655 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14657 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14659 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14661 /* Now create the move. */
14663 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14665 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14670 /* Allocate a 64-bit stack slot to be used for copying SDmode
14671 values through if this function has any SDmode references. */
14674 rs6000_alloc_sdmode_stack_slot (void)
14678 gimple_stmt_iterator gsi;
14680 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14683 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14685 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14688 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14689 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14695 /* Check for any SDmode parameters of the function. */
14696 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14698 if (TREE_TYPE (t) == error_mark_node)
14701 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14702 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14704 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14705 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14713 rs6000_instantiate_decls (void)
14715 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14716 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14719 /* Given an rtx X being reloaded into a reg required to be
14720 in class CLASS, return the class of reg to actually use.
14721 In general this is just CLASS; but on some machines
14722 in some cases it is preferable to use a more restrictive class.
14724 On the RS/6000, we have to return NO_REGS when we want to reload a
14725 floating-point CONST_DOUBLE to force it to be copied to memory.
14727 We also don't want to reload integer values into floating-point
14728 registers if we can at all help it. In fact, this can
14729 cause reload to die, if it tries to generate a reload of CTR
14730 into a FP register and discovers it doesn't have the memory location
14733 ??? Would it be a good idea to have reload do the converse, that is
14734 try to reload floating modes into FP registers if possible?
14737 static enum reg_class
14738 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14740 enum machine_mode mode = GET_MODE (x);
14742 if (VECTOR_UNIT_VSX_P (mode)
14743 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14746 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14747 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14748 && easy_vector_constant (x, mode))
14749 return ALTIVEC_REGS;
14751 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14754 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14755 return GENERAL_REGS;
14757 /* For VSX, prefer the traditional registers for 64-bit values because we can
14758 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14759 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14760 prefer Altivec loads.. */
14761 if (rclass == VSX_REGS)
14763 if (GET_MODE_SIZE (mode) <= 8)
14766 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14767 return ALTIVEC_REGS;
14775 /* Debug version of rs6000_preferred_reload_class. */
14776 static enum reg_class
14777 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14779 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14782 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14784 reg_class_names[ret], reg_class_names[rclass],
14785 GET_MODE_NAME (GET_MODE (x)));
14791 /* If we are copying between FP or AltiVec registers and anything else, we need
14792 a memory location. The exception is when we are targeting ppc64 and the
14793 move to/from fpr to gpr instructions are available. Also, under VSX, you
14794 can copy vector registers from the FP register set to the Altivec register
14795 set and vice versa. */
14798 rs6000_secondary_memory_needed (enum reg_class class1,
14799 enum reg_class class2,
14800 enum machine_mode mode)
14802 if (class1 == class2)
14805 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14806 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14807 between these classes. But we need memory for other things that can go in
14808 FLOAT_REGS like SFmode. */
14810 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14811 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14812 || class1 == FLOAT_REGS))
14813 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14814 && class2 != FLOAT_REGS);
14816 if (class1 == VSX_REGS || class2 == VSX_REGS)
14819 if (class1 == FLOAT_REGS
14820 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14821 || ((mode != DFmode)
14822 && (mode != DDmode)
14823 && (mode != DImode))))
14826 if (class2 == FLOAT_REGS
14827 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14828 || ((mode != DFmode)
14829 && (mode != DDmode)
14830 && (mode != DImode))))
14833 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14839 /* Debug version of rs6000_secondary_memory_needed. */
14841 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14842 enum reg_class class2,
14843 enum machine_mode mode)
14845 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14848 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14849 "class2 = %s, mode = %s\n",
14850 ret ? "true" : "false", reg_class_names[class1],
14851 reg_class_names[class2], GET_MODE_NAME (mode));
14856 /* Return the register class of a scratch register needed to copy IN into
14857 or out of a register in RCLASS in MODE. If it can be done directly,
14858 NO_REGS is returned. */
14860 static enum reg_class
14861 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14866 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14868 && MACHOPIC_INDIRECT
14872 /* We cannot copy a symbolic operand directly into anything
14873 other than BASE_REGS for TARGET_ELF. So indicate that a
14874 register from BASE_REGS is needed as an intermediate
14877 On Darwin, pic addresses require a load from memory, which
14878 needs a base register. */
14879 if (rclass != BASE_REGS
14880 && (GET_CODE (in) == SYMBOL_REF
14881 || GET_CODE (in) == HIGH
14882 || GET_CODE (in) == LABEL_REF
14883 || GET_CODE (in) == CONST))
14887 if (GET_CODE (in) == REG)
14889 regno = REGNO (in);
14890 if (regno >= FIRST_PSEUDO_REGISTER)
14892 regno = true_regnum (in);
14893 if (regno >= FIRST_PSEUDO_REGISTER)
14897 else if (GET_CODE (in) == SUBREG)
14899 regno = true_regnum (in);
14900 if (regno >= FIRST_PSEUDO_REGISTER)
14906 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14908 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14909 || (regno >= 0 && INT_REGNO_P (regno)))
14912 /* Constants, memory, and FP registers can go into FP registers. */
14913 if ((regno == -1 || FP_REGNO_P (regno))
14914 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14915 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14917 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14920 && (regno == -1 || VSX_REGNO_P (regno))
14921 && VSX_REG_CLASS_P (rclass))
14924 /* Memory, and AltiVec registers can go into AltiVec registers. */
14925 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14926 && rclass == ALTIVEC_REGS)
14929 /* We can copy among the CR registers. */
14930 if ((rclass == CR_REGS || rclass == CR0_REGS)
14931 && regno >= 0 && CR_REGNO_P (regno))
14934 /* Otherwise, we need GENERAL_REGS. */
14935 return GENERAL_REGS;
14938 /* Debug version of rs6000_secondary_reload_class. */
14939 static enum reg_class
14940 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14941 enum machine_mode mode, rtx in)
14943 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14945 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14946 "mode = %s, input rtx:\n",
14947 reg_class_names[ret], reg_class_names[rclass],
14948 GET_MODE_NAME (mode));
14954 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14957 rs6000_cannot_change_mode_class (enum machine_mode from,
14958 enum machine_mode to,
14959 enum reg_class rclass)
14961 unsigned from_size = GET_MODE_SIZE (from);
14962 unsigned to_size = GET_MODE_SIZE (to);
14964 if (from_size != to_size)
14966 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14967 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14968 && reg_classes_intersect_p (xclass, rclass));
14971 if (TARGET_E500_DOUBLE
14972 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14973 || (((to) == TFmode) + ((from) == TFmode)) == 1
14974 || (((to) == DDmode) + ((from) == DDmode)) == 1
14975 || (((to) == TDmode) + ((from) == TDmode)) == 1
14976 || (((to) == DImode) + ((from) == DImode)) == 1))
14979 /* Since the VSX register set includes traditional floating point registers
14980 and altivec registers, just check for the size being different instead of
14981 trying to check whether the modes are vector modes. Otherwise it won't
14982 allow say DF and DI to change classes. */
14983 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14984 return (from_size != 8 && from_size != 16);
14986 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14987 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14990 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14991 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14997 /* Debug version of rs6000_cannot_change_mode_class. */
14999 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15000 enum machine_mode to,
15001 enum reg_class rclass)
15003 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15006 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15007 "to = %s, rclass = %s\n",
15008 ret ? "true" : "false",
15009 GET_MODE_NAME (from), GET_MODE_NAME (to),
15010 reg_class_names[rclass]);
15015 /* Given a comparison operation, return the bit number in CCR to test. We
15016 know this is a valid comparison.
15018 SCC_P is 1 if this is for an scc. That means that %D will have been
15019 used instead of %C, so the bits will be in different places.
15021 Return -1 if OP isn't a valid comparison for some reason. */
15024 ccr_bit (rtx op, int scc_p)
15026 enum rtx_code code = GET_CODE (op);
15027 enum machine_mode cc_mode;
15032 if (!COMPARISON_P (op))
15035 reg = XEXP (op, 0);
15037 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15039 cc_mode = GET_MODE (reg);
15040 cc_regnum = REGNO (reg);
15041 base_bit = 4 * (cc_regnum - CR0_REGNO);
15043 validate_condition_mode (code, cc_mode);
15045 /* When generating a sCOND operation, only positive conditions are
15048 || code == EQ || code == GT || code == LT || code == UNORDERED
15049 || code == GTU || code == LTU);
15054 return scc_p ? base_bit + 3 : base_bit + 2;
15056 return base_bit + 2;
15057 case GT: case GTU: case UNLE:
15058 return base_bit + 1;
15059 case LT: case LTU: case UNGE:
15061 case ORDERED: case UNORDERED:
15062 return base_bit + 3;
15065 /* If scc, we will have done a cror to put the bit in the
15066 unordered position. So test that bit. For integer, this is ! LT
15067 unless this is an scc insn. */
15068 return scc_p ? base_bit + 3 : base_bit;
15071 return scc_p ? base_bit + 3 : base_bit + 1;
15074 gcc_unreachable ();
15078 /* Return the GOT register. */
15081 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15083 /* The second flow pass currently (June 1999) can't update
15084 regs_ever_live without disturbing other parts of the compiler, so
15085 update it here to make the prolog/epilogue code happy. */
15086 if (!can_create_pseudo_p ()
15087 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15088 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15090 crtl->uses_pic_offset_table = 1;
15092 return pic_offset_table_rtx;
15095 static rs6000_stack_t stack_info;
15097 /* Function to init struct machine_function.
15098 This will be called, via a pointer variable,
15099 from push_function_context. */
15101 static struct machine_function *
15102 rs6000_init_machine_status (void)
15104 stack_info.reload_completed = 0;
15105 return ggc_alloc_cleared_machine_function ();
15108 /* These macros test for integers and extract the low-order bits. */
15110 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15111 && GET_MODE (X) == VOIDmode)
15113 #define INT_LOWPART(X) \
15114 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15117 extract_MB (rtx op)
15120 unsigned long val = INT_LOWPART (op);
15122 /* If the high bit is zero, the value is the first 1 bit we find
15124 if ((val & 0x80000000) == 0)
15126 gcc_assert (val & 0xffffffff);
15129 while (((val <<= 1) & 0x80000000) == 0)
15134 /* If the high bit is set and the low bit is not, or the mask is all
15135 1's, the value is zero. */
15136 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15139 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15142 while (((val >>= 1) & 1) != 0)
15149 extract_ME (rtx op)
15152 unsigned long val = INT_LOWPART (op);
15154 /* If the low bit is zero, the value is the first 1 bit we find from
15156 if ((val & 1) == 0)
15158 gcc_assert (val & 0xffffffff);
15161 while (((val >>= 1) & 1) == 0)
15167 /* If the low bit is set and the high bit is not, or the mask is all
15168 1's, the value is 31. */
15169 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15172 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15175 while (((val <<= 1) & 0x80000000) != 0)
15181 /* Locate some local-dynamic symbol still in use by this function
15182 so that we can print its name in some tls_ld pattern. */
15184 static const char *
15185 rs6000_get_some_local_dynamic_name (void)
15189 if (cfun->machine->some_ld_name)
15190 return cfun->machine->some_ld_name;
15192 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15194 && for_each_rtx (&PATTERN (insn),
15195 rs6000_get_some_local_dynamic_name_1, 0))
15196 return cfun->machine->some_ld_name;
15198 gcc_unreachable ();
15201 /* Helper function for rs6000_get_some_local_dynamic_name. */
15204 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15208 if (GET_CODE (x) == SYMBOL_REF)
15210 const char *str = XSTR (x, 0);
15211 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15213 cfun->machine->some_ld_name = str;
15221 /* Write out a function code label. */
15224 rs6000_output_function_entry (FILE *file, const char *fname)
15226 if (fname[0] != '.')
15228 switch (DEFAULT_ABI)
15231 gcc_unreachable ();
15237 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15246 RS6000_OUTPUT_BASENAME (file, fname);
15249 /* Print an operand. Recognize special options, documented below. */
15252 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15253 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15255 #define SMALL_DATA_RELOC "sda21"
15256 #define SMALL_DATA_REG 0
15260 print_operand (FILE *file, rtx x, int code)
15264 unsigned HOST_WIDE_INT uval;
15269 /* Write out an instruction after the call which may be replaced
15270 with glue code by the loader. This depends on the AIX version. */
15271 asm_fprintf (file, RS6000_CALL_GLUE);
15274 /* %a is output_address. */
15277 /* If X is a constant integer whose low-order 5 bits are zero,
15278 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15279 in the AIX assembler where "sri" with a zero shift count
15280 writes a trash instruction. */
15281 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15288 /* If constant, low-order 16 bits of constant, unsigned.
15289 Otherwise, write normally. */
15291 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15293 print_operand (file, x, 0);
15297 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15298 for 64-bit mask direction. */
15299 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15302 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15306 /* X is a CR register. Print the number of the GT bit of the CR. */
15307 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15308 output_operand_lossage ("invalid %%c value");
15310 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15314 /* Like 'J' but get to the GT bit only. */
15315 gcc_assert (GET_CODE (x) == REG);
15317 /* Bit 1 is GT bit. */
15318 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15320 /* Add one for shift count in rlinm for scc. */
15321 fprintf (file, "%d", i + 1);
15325 /* X is a CR register. Print the number of the EQ bit of the CR */
15326 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15327 output_operand_lossage ("invalid %%E value");
15329 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15333 /* X is a CR register. Print the shift count needed to move it
15334 to the high-order four bits. */
15335 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15336 output_operand_lossage ("invalid %%f value");
15338 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15342 /* Similar, but print the count for the rotate in the opposite
15344 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15345 output_operand_lossage ("invalid %%F value");
15347 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15351 /* X is a constant integer. If it is negative, print "m",
15352 otherwise print "z". This is to make an aze or ame insn. */
15353 if (GET_CODE (x) != CONST_INT)
15354 output_operand_lossage ("invalid %%G value");
15355 else if (INTVAL (x) >= 0)
15362 /* If constant, output low-order five bits. Otherwise, write
15365 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15367 print_operand (file, x, 0);
15371 /* If constant, output low-order six bits. Otherwise, write
15374 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15376 print_operand (file, x, 0);
15380 /* Print `i' if this is a constant, else nothing. */
15386 /* Write the bit number in CCR for jump. */
15387 i = ccr_bit (x, 0);
15389 output_operand_lossage ("invalid %%j code");
15391 fprintf (file, "%d", i);
15395 /* Similar, but add one for shift count in rlinm for scc and pass
15396 scc flag to `ccr_bit'. */
15397 i = ccr_bit (x, 1);
15399 output_operand_lossage ("invalid %%J code");
15401 /* If we want bit 31, write a shift count of zero, not 32. */
15402 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15406 /* X must be a constant. Write the 1's complement of the
15409 output_operand_lossage ("invalid %%k value");
15411 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15415 /* X must be a symbolic constant on ELF. Write an
15416 expression suitable for an 'addi' that adds in the low 16
15417 bits of the MEM. */
15418 if (GET_CODE (x) == CONST)
15420 if (GET_CODE (XEXP (x, 0)) != PLUS
15421 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15422 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15423 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15424 output_operand_lossage ("invalid %%K value");
15426 print_operand_address (file, x);
15427 fputs ("@l", file);
15430 /* %l is output_asm_label. */
15433 /* Write second word of DImode or DFmode reference. Works on register
15434 or non-indexed memory only. */
15435 if (GET_CODE (x) == REG)
15436 fputs (reg_names[REGNO (x) + 1], file);
15437 else if (GET_CODE (x) == MEM)
15439 /* Handle possible auto-increment. Since it is pre-increment and
15440 we have already done it, we can just use an offset of word. */
15441 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15442 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15443 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15445 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15446 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15449 output_address (XEXP (adjust_address_nv (x, SImode,
15453 if (small_data_operand (x, GET_MODE (x)))
15454 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15455 reg_names[SMALL_DATA_REG]);
15460 /* MB value for a mask operand. */
15461 if (! mask_operand (x, SImode))
15462 output_operand_lossage ("invalid %%m value");
15464 fprintf (file, "%d", extract_MB (x));
15468 /* ME value for a mask operand. */
15469 if (! mask_operand (x, SImode))
15470 output_operand_lossage ("invalid %%M value");
15472 fprintf (file, "%d", extract_ME (x));
15475 /* %n outputs the negative of its operand. */
15478 /* Write the number of elements in the vector times 4. */
15479 if (GET_CODE (x) != PARALLEL)
15480 output_operand_lossage ("invalid %%N value");
15482 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15486 /* Similar, but subtract 1 first. */
15487 if (GET_CODE (x) != PARALLEL)
15488 output_operand_lossage ("invalid %%O value");
15490 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15494 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15496 || INT_LOWPART (x) < 0
15497 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15498 output_operand_lossage ("invalid %%p value");
15500 fprintf (file, "%d", i);
15504 /* The operand must be an indirect memory reference. The result
15505 is the register name. */
15506 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15507 || REGNO (XEXP (x, 0)) >= 32)
15508 output_operand_lossage ("invalid %%P value");
15510 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15514 /* This outputs the logical code corresponding to a boolean
15515 expression. The expression may have one or both operands
15516 negated (if one, only the first one). For condition register
15517 logical operations, it will also treat the negated
15518 CR codes as NOTs, but not handle NOTs of them. */
15520 const char *const *t = 0;
15522 enum rtx_code code = GET_CODE (x);
15523 static const char * const tbl[3][3] = {
15524 { "and", "andc", "nor" },
15525 { "or", "orc", "nand" },
15526 { "xor", "eqv", "xor" } };
15530 else if (code == IOR)
15532 else if (code == XOR)
15535 output_operand_lossage ("invalid %%q value");
15537 if (GET_CODE (XEXP (x, 0)) != NOT)
15541 if (GET_CODE (XEXP (x, 1)) == NOT)
15559 /* X is a CR register. Print the mask for `mtcrf'. */
15560 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15561 output_operand_lossage ("invalid %%R value");
15563 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15567 /* Low 5 bits of 32 - value */
15569 output_operand_lossage ("invalid %%s value");
15571 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15575 /* PowerPC64 mask position. All 0's is excluded.
15576 CONST_INT 32-bit mask is considered sign-extended so any
15577 transition must occur within the CONST_INT, not on the boundary. */
15578 if (! mask64_operand (x, DImode))
15579 output_operand_lossage ("invalid %%S value");
15581 uval = INT_LOWPART (x);
15583 if (uval & 1) /* Clear Left */
15585 #if HOST_BITS_PER_WIDE_INT > 64
15586 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15590 else /* Clear Right */
15593 #if HOST_BITS_PER_WIDE_INT > 64
15594 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15600 gcc_assert (i >= 0);
15601 fprintf (file, "%d", i);
15605 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15606 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15608 /* Bit 3 is OV bit. */
15609 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15611 /* If we want bit 31, write a shift count of zero, not 32. */
15612 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15616 /* Print the symbolic name of a branch target register. */
15617 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15618 && REGNO (x) != CTR_REGNO))
15619 output_operand_lossage ("invalid %%T value");
15620 else if (REGNO (x) == LR_REGNO)
15621 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15623 fputs ("ctr", file);
15627 /* High-order 16 bits of constant for use in unsigned operand. */
15629 output_operand_lossage ("invalid %%u value");
15631 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15632 (INT_LOWPART (x) >> 16) & 0xffff);
15636 /* High-order 16 bits of constant for use in signed operand. */
15638 output_operand_lossage ("invalid %%v value");
15640 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15641 (INT_LOWPART (x) >> 16) & 0xffff);
15645 /* Print `u' if this has an auto-increment or auto-decrement. */
15646 if (GET_CODE (x) == MEM
15647 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15648 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15649 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15654 /* Print the trap code for this operand. */
15655 switch (GET_CODE (x))
15658 fputs ("eq", file); /* 4 */
15661 fputs ("ne", file); /* 24 */
15664 fputs ("lt", file); /* 16 */
15667 fputs ("le", file); /* 20 */
15670 fputs ("gt", file); /* 8 */
15673 fputs ("ge", file); /* 12 */
15676 fputs ("llt", file); /* 2 */
15679 fputs ("lle", file); /* 6 */
15682 fputs ("lgt", file); /* 1 */
15685 fputs ("lge", file); /* 5 */
15688 gcc_unreachable ();
15693 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15696 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15697 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15699 print_operand (file, x, 0);
15703 /* MB value for a PowerPC64 rldic operand. */
15704 val = (GET_CODE (x) == CONST_INT
15705 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15710 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15711 if ((val <<= 1) < 0)
15714 #if HOST_BITS_PER_WIDE_INT == 32
15715 if (GET_CODE (x) == CONST_INT && i >= 0)
15716 i += 32; /* zero-extend high-part was all 0's */
15717 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15719 val = CONST_DOUBLE_LOW (x);
15725 for ( ; i < 64; i++)
15726 if ((val <<= 1) < 0)
15731 fprintf (file, "%d", i + 1);
15735 /* X is a FPR or Altivec register used in a VSX context. */
15736 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15737 output_operand_lossage ("invalid %%x value");
15740 int reg = REGNO (x);
15741 int vsx_reg = (FP_REGNO_P (reg)
15743 : reg - FIRST_ALTIVEC_REGNO + 32);
15745 #ifdef TARGET_REGNAMES
15746 if (TARGET_REGNAMES)
15747 fprintf (file, "%%vs%d", vsx_reg);
15750 fprintf (file, "%d", vsx_reg);
15755 if (GET_CODE (x) == MEM
15756 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15757 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15758 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15763 /* Like 'L', for third word of TImode */
15764 if (GET_CODE (x) == REG)
15765 fputs (reg_names[REGNO (x) + 2], file);
15766 else if (GET_CODE (x) == MEM)
15768 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15769 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15770 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15771 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15772 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15774 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15775 if (small_data_operand (x, GET_MODE (x)))
15776 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15777 reg_names[SMALL_DATA_REG]);
15782 /* X is a SYMBOL_REF. Write out the name preceded by a
15783 period and without any trailing data in brackets. Used for function
15784 names. If we are configured for System V (or the embedded ABI) on
15785 the PowerPC, do not emit the period, since those systems do not use
15786 TOCs and the like. */
15787 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15789 /* Mark the decl as referenced so that cgraph will output the
15791 if (SYMBOL_REF_DECL (x))
15792 mark_decl_referenced (SYMBOL_REF_DECL (x));
15794 /* For macho, check to see if we need a stub. */
15797 const char *name = XSTR (x, 0);
15799 if (darwin_emit_branch_islands
15800 && MACHOPIC_INDIRECT
15801 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15802 name = machopic_indirection_name (x, /*stub_p=*/true);
15804 assemble_name (file, name);
15806 else if (!DOT_SYMBOLS)
15807 assemble_name (file, XSTR (x, 0));
15809 rs6000_output_function_entry (file, XSTR (x, 0));
15813 /* Like 'L', for last word of TImode. */
15814 if (GET_CODE (x) == REG)
15815 fputs (reg_names[REGNO (x) + 3], file);
15816 else if (GET_CODE (x) == MEM)
15818 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15819 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15820 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15821 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15822 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15824 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15825 if (small_data_operand (x, GET_MODE (x)))
15826 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15827 reg_names[SMALL_DATA_REG]);
15831 /* Print AltiVec or SPE memory operand. */
15836 gcc_assert (GET_CODE (x) == MEM);
15840 /* Ugly hack because %y is overloaded. */
15841 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15842 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15843 || GET_MODE (x) == TFmode
15844 || GET_MODE (x) == TImode))
15846 /* Handle [reg]. */
15847 if (GET_CODE (tmp) == REG)
15849 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15852 /* Handle [reg+UIMM]. */
15853 else if (GET_CODE (tmp) == PLUS &&
15854 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15858 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15860 x = INTVAL (XEXP (tmp, 1));
15861 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15865 /* Fall through. Must be [reg+reg]. */
15867 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15868 && GET_CODE (tmp) == AND
15869 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15870 && INTVAL (XEXP (tmp, 1)) == -16)
15871 tmp = XEXP (tmp, 0);
15872 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15873 && GET_CODE (tmp) == PRE_MODIFY)
15874 tmp = XEXP (tmp, 1);
15875 if (GET_CODE (tmp) == REG)
15876 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15879 if (!GET_CODE (tmp) == PLUS
15880 || !REG_P (XEXP (tmp, 0))
15881 || !REG_P (XEXP (tmp, 1)))
15883 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15887 if (REGNO (XEXP (tmp, 0)) == 0)
15888 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15889 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15891 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15892 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15898 if (GET_CODE (x) == REG)
15899 fprintf (file, "%s", reg_names[REGNO (x)]);
15900 else if (GET_CODE (x) == MEM)
15902 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15903 know the width from the mode. */
15904 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15905 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15906 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15907 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15908 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15909 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15910 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15911 output_address (XEXP (XEXP (x, 0), 1));
15913 output_address (XEXP (x, 0));
15917 if (toc_relative_expr_p (x))
15918 /* This hack along with a corresponding hack in
15919 rs6000_output_addr_const_extra arranges to output addends
15920 where the assembler expects to find them. eg.
15921 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15922 without this hack would be output as "x@toc+4". We
15924 output_addr_const (file, tocrel_base);
15926 output_addr_const (file, x);
15931 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15935 output_operand_lossage ("invalid %%xn code");
15939 /* Print the address of an operand. */
15942 print_operand_address (FILE *file, rtx x)
15944 if (GET_CODE (x) == REG)
15945 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15946 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15947 || GET_CODE (x) == LABEL_REF)
15949 output_addr_const (file, x);
15950 if (small_data_operand (x, GET_MODE (x)))
15951 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15952 reg_names[SMALL_DATA_REG]);
15954 gcc_assert (!TARGET_TOC);
15956 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15958 gcc_assert (REG_P (XEXP (x, 0)));
15959 if (REGNO (XEXP (x, 0)) == 0)
15960 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15961 reg_names[ REGNO (XEXP (x, 0)) ]);
15963 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15964 reg_names[ REGNO (XEXP (x, 1)) ]);
15966 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15967 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15968 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15970 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15971 && CONSTANT_P (XEXP (x, 1)))
15973 fprintf (file, "lo16(");
15974 output_addr_const (file, XEXP (x, 1));
15975 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15978 else if (legitimate_constant_pool_address_p (x, QImode, true))
15980 /* This hack along with a corresponding hack in
15981 rs6000_output_addr_const_extra arranges to output addends
15982 where the assembler expects to find them. eg.
15984 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15985 without this hack would be output as "x@toc+8@l(9)". We
15986 want "x+8@toc@l(9)". */
15987 output_addr_const (file, tocrel_base);
15988 if (GET_CODE (x) == LO_SUM)
15989 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15991 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15994 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15995 && CONSTANT_P (XEXP (x, 1)))
15997 output_addr_const (file, XEXP (x, 1));
15998 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16002 gcc_unreachable ();
16005 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16008 rs6000_output_addr_const_extra (FILE *file, rtx x)
16010 if (GET_CODE (x) == UNSPEC)
16011 switch (XINT (x, 1))
16013 case UNSPEC_TOCREL:
16014 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16015 output_addr_const (file, XVECEXP (x, 0, 0));
16016 if (x == tocrel_base && tocrel_offset != const0_rtx)
16018 if (INTVAL (tocrel_offset) >= 0)
16019 fprintf (file, "+");
16020 output_addr_const (file, tocrel_offset);
16022 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16025 assemble_name (file, toc_label_name);
16027 else if (TARGET_ELF)
16028 fputs ("@toc", file);
16032 case UNSPEC_MACHOPIC_OFFSET:
16033 output_addr_const (file, XVECEXP (x, 0, 0));
16035 machopic_output_function_base_name (file);
16042 /* Target hook for assembling integer objects. The PowerPC version has
16043 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16044 is defined. It also needs to handle DI-mode objects on 64-bit
16048 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16050 #ifdef RELOCATABLE_NEEDS_FIXUP
16051 /* Special handling for SI values. */
16052 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16054 static int recurse = 0;
16056 /* For -mrelocatable, we mark all addresses that need to be fixed up
16057 in the .fixup section. */
16058 if (TARGET_RELOCATABLE
16059 && in_section != toc_section
16060 && in_section != text_section
16061 && !unlikely_text_section_p (in_section)
16063 && GET_CODE (x) != CONST_INT
16064 && GET_CODE (x) != CONST_DOUBLE
16070 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16072 ASM_OUTPUT_LABEL (asm_out_file, buf);
16073 fprintf (asm_out_file, "\t.long\t(");
16074 output_addr_const (asm_out_file, x);
16075 fprintf (asm_out_file, ")@fixup\n");
16076 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16077 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16078 fprintf (asm_out_file, "\t.long\t");
16079 assemble_name (asm_out_file, buf);
16080 fprintf (asm_out_file, "\n\t.previous\n");
16084 /* Remove initial .'s to turn a -mcall-aixdesc function
16085 address into the address of the descriptor, not the function
16087 else if (GET_CODE (x) == SYMBOL_REF
16088 && XSTR (x, 0)[0] == '.'
16089 && DEFAULT_ABI == ABI_AIX)
16091 const char *name = XSTR (x, 0);
16092 while (*name == '.')
16095 fprintf (asm_out_file, "\t.long\t%s\n", name);
16099 #endif /* RELOCATABLE_NEEDS_FIXUP */
16100 return default_assemble_integer (x, size, aligned_p);
16103 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16104 /* Emit an assembler directive to set symbol visibility for DECL to
16105 VISIBILITY_TYPE. */
16108 rs6000_assemble_visibility (tree decl, int vis)
16110 /* Functions need to have their entry point symbol visibility set as
16111 well as their descriptor symbol visibility. */
16112 if (DEFAULT_ABI == ABI_AIX
16114 && TREE_CODE (decl) == FUNCTION_DECL)
16116 static const char * const visibility_types[] = {
16117 NULL, "internal", "hidden", "protected"
16120 const char *name, *type;
16122 name = ((* targetm.strip_name_encoding)
16123 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16124 type = visibility_types[vis];
16126 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16127 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16130 default_assemble_visibility (decl, vis);
16135 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16137 /* Reversal of FP compares takes care -- an ordered compare
16138 becomes an unordered compare and vice versa. */
16139 if (mode == CCFPmode
16140 && (!flag_finite_math_only
16141 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16142 || code == UNEQ || code == LTGT))
16143 return reverse_condition_maybe_unordered (code);
16145 return reverse_condition (code);
16148 /* Generate a compare for CODE. Return a brand-new rtx that
16149 represents the result of the compare. */
16152 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16154 enum machine_mode comp_mode;
16155 rtx compare_result;
16156 enum rtx_code code = GET_CODE (cmp);
16157 rtx op0 = XEXP (cmp, 0);
16158 rtx op1 = XEXP (cmp, 1);
16160 if (FLOAT_MODE_P (mode))
16161 comp_mode = CCFPmode;
16162 else if (code == GTU || code == LTU
16163 || code == GEU || code == LEU)
16164 comp_mode = CCUNSmode;
16165 else if ((code == EQ || code == NE)
16166 && GET_CODE (op0) == SUBREG
16167 && GET_CODE (op1) == SUBREG
16168 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16169 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16170 /* These are unsigned values, perhaps there will be a later
16171 ordering compare that can be shared with this one.
16172 Unfortunately we cannot detect the signedness of the operands
16173 for non-subregs. */
16174 comp_mode = CCUNSmode;
16176 comp_mode = CCmode;
16178 /* First, the compare. */
16179 compare_result = gen_reg_rtx (comp_mode);
16181 /* E500 FP compare instructions on the GPRs. Yuck! */
16182 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16183 && FLOAT_MODE_P (mode))
16185 rtx cmp, or_result, compare_result2;
16186 enum machine_mode op_mode = GET_MODE (op0);
16188 if (op_mode == VOIDmode)
16189 op_mode = GET_MODE (op1);
16191 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16192 This explains the following mess. */
16196 case EQ: case UNEQ: case NE: case LTGT:
16200 cmp = (flag_finite_math_only && !flag_trapping_math)
16201 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16202 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16206 cmp = (flag_finite_math_only && !flag_trapping_math)
16207 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16208 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16212 cmp = (flag_finite_math_only && !flag_trapping_math)
16213 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16214 : gen_cmptfeq_gpr (compare_result, op0, op1);
16218 gcc_unreachable ();
16222 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16226 cmp = (flag_finite_math_only && !flag_trapping_math)
16227 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16228 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16232 cmp = (flag_finite_math_only && !flag_trapping_math)
16233 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16234 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16238 cmp = (flag_finite_math_only && !flag_trapping_math)
16239 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16240 : gen_cmptfgt_gpr (compare_result, op0, op1);
16244 gcc_unreachable ();
16248 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16252 cmp = (flag_finite_math_only && !flag_trapping_math)
16253 ? gen_tstsflt_gpr (compare_result, op0, op1)
16254 : gen_cmpsflt_gpr (compare_result, op0, op1);
16258 cmp = (flag_finite_math_only && !flag_trapping_math)
16259 ? gen_tstdflt_gpr (compare_result, op0, op1)
16260 : gen_cmpdflt_gpr (compare_result, op0, op1);
16264 cmp = (flag_finite_math_only && !flag_trapping_math)
16265 ? gen_tsttflt_gpr (compare_result, op0, op1)
16266 : gen_cmptflt_gpr (compare_result, op0, op1);
16270 gcc_unreachable ();
16274 gcc_unreachable ();
16277 /* Synthesize LE and GE from LT/GT || EQ. */
16278 if (code == LE || code == GE || code == LEU || code == GEU)
16284 case LE: code = LT; break;
16285 case GE: code = GT; break;
16286 case LEU: code = LT; break;
16287 case GEU: code = GT; break;
16288 default: gcc_unreachable ();
16291 compare_result2 = gen_reg_rtx (CCFPmode);
16297 cmp = (flag_finite_math_only && !flag_trapping_math)
16298 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16299 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16303 cmp = (flag_finite_math_only && !flag_trapping_math)
16304 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16305 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16309 cmp = (flag_finite_math_only && !flag_trapping_math)
16310 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16311 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16315 gcc_unreachable ();
16319 /* OR them together. */
16320 or_result = gen_reg_rtx (CCFPmode);
16321 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16323 compare_result = or_result;
16328 if (code == NE || code == LTGT)
16338 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16339 CLOBBERs to match cmptf_internal2 pattern. */
16340 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16341 && GET_MODE (op0) == TFmode
16342 && !TARGET_IEEEQUAD
16343 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16344 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16346 gen_rtx_SET (VOIDmode,
16348 gen_rtx_COMPARE (comp_mode, op0, op1)),
16349 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16350 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16351 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16352 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16353 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16354 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16355 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16356 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16357 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16358 else if (GET_CODE (op1) == UNSPEC
16359 && XINT (op1, 1) == UNSPEC_SP_TEST)
16361 rtx op1b = XVECEXP (op1, 0, 0);
16362 comp_mode = CCEQmode;
16363 compare_result = gen_reg_rtx (CCEQmode);
16365 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16367 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16370 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16371 gen_rtx_COMPARE (comp_mode, op0, op1)));
16374 /* Some kinds of FP comparisons need an OR operation;
16375 under flag_finite_math_only we don't bother. */
16376 if (FLOAT_MODE_P (mode)
16377 && !flag_finite_math_only
16378 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16379 && (code == LE || code == GE
16380 || code == UNEQ || code == LTGT
16381 || code == UNGT || code == UNLT))
16383 enum rtx_code or1, or2;
16384 rtx or1_rtx, or2_rtx, compare2_rtx;
16385 rtx or_result = gen_reg_rtx (CCEQmode);
16389 case LE: or1 = LT; or2 = EQ; break;
16390 case GE: or1 = GT; or2 = EQ; break;
16391 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16392 case LTGT: or1 = LT; or2 = GT; break;
16393 case UNGT: or1 = UNORDERED; or2 = GT; break;
16394 case UNLT: or1 = UNORDERED; or2 = LT; break;
16395 default: gcc_unreachable ();
16397 validate_condition_mode (or1, comp_mode);
16398 validate_condition_mode (or2, comp_mode);
16399 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16400 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16401 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16402 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16404 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16406 compare_result = or_result;
16410 validate_condition_mode (code, GET_MODE (compare_result));
16412 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16416 /* Emit the RTL for an sISEL pattern. */
16419 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16421 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16425 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16428 enum machine_mode op_mode;
16429 enum rtx_code cond_code;
16430 rtx result = operands[0];
16432 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16434 rs6000_emit_sISEL (mode, operands);
16438 condition_rtx = rs6000_generate_compare (operands[1], mode);
16439 cond_code = GET_CODE (condition_rtx);
16441 if (FLOAT_MODE_P (mode)
16442 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16446 PUT_MODE (condition_rtx, SImode);
16447 t = XEXP (condition_rtx, 0);
16449 gcc_assert (cond_code == NE || cond_code == EQ);
16451 if (cond_code == NE)
16452 emit_insn (gen_e500_flip_gt_bit (t, t));
16454 emit_insn (gen_move_from_CR_gt_bit (result, t));
16458 if (cond_code == NE
16459 || cond_code == GE || cond_code == LE
16460 || cond_code == GEU || cond_code == LEU
16461 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16463 rtx not_result = gen_reg_rtx (CCEQmode);
16464 rtx not_op, rev_cond_rtx;
16465 enum machine_mode cc_mode;
16467 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16469 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16470 SImode, XEXP (condition_rtx, 0), const0_rtx);
16471 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16472 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16473 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16476 op_mode = GET_MODE (XEXP (operands[1], 0));
16477 if (op_mode == VOIDmode)
16478 op_mode = GET_MODE (XEXP (operands[1], 1));
16480 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16482 PUT_MODE (condition_rtx, DImode);
16483 convert_move (result, condition_rtx, 0);
16487 PUT_MODE (condition_rtx, SImode);
16488 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16492 /* Emit a branch of kind CODE to location LOC. */
16495 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16497 rtx condition_rtx, loc_ref;
16499 condition_rtx = rs6000_generate_compare (operands[0], mode);
16500 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16501 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16502 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16503 loc_ref, pc_rtx)));
16506 /* Return the string to output a conditional branch to LABEL, which is
16507 the operand number of the label, or -1 if the branch is really a
16508 conditional return.
16510 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16511 condition code register and its mode specifies what kind of
16512 comparison we made.
16514 REVERSED is nonzero if we should reverse the sense of the comparison.
16516 INSN is the insn. */
16519 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16521 static char string[64];
16522 enum rtx_code code = GET_CODE (op);
16523 rtx cc_reg = XEXP (op, 0);
16524 enum machine_mode mode = GET_MODE (cc_reg);
16525 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16526 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16527 int really_reversed = reversed ^ need_longbranch;
16533 validate_condition_mode (code, mode);
16535 /* Work out which way this really branches. We could use
16536 reverse_condition_maybe_unordered here always but this
16537 makes the resulting assembler clearer. */
16538 if (really_reversed)
16540 /* Reversal of FP compares takes care -- an ordered compare
16541 becomes an unordered compare and vice versa. */
16542 if (mode == CCFPmode)
16543 code = reverse_condition_maybe_unordered (code);
16545 code = reverse_condition (code);
16548 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16550 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16555 /* Opposite of GT. */
16564 gcc_unreachable ();
16570 /* Not all of these are actually distinct opcodes, but
16571 we distinguish them for clarity of the resulting assembler. */
16572 case NE: case LTGT:
16573 ccode = "ne"; break;
16574 case EQ: case UNEQ:
16575 ccode = "eq"; break;
16577 ccode = "ge"; break;
16578 case GT: case GTU: case UNGT:
16579 ccode = "gt"; break;
16581 ccode = "le"; break;
16582 case LT: case LTU: case UNLT:
16583 ccode = "lt"; break;
16584 case UNORDERED: ccode = "un"; break;
16585 case ORDERED: ccode = "nu"; break;
16586 case UNGE: ccode = "nl"; break;
16587 case UNLE: ccode = "ng"; break;
16589 gcc_unreachable ();
16592 /* Maybe we have a guess as to how likely the branch is.
16593 The old mnemonics don't have a way to specify this information. */
16595 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16596 if (note != NULL_RTX)
16598 /* PROB is the difference from 50%. */
16599 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16601 /* Only hint for highly probable/improbable branches on newer
16602 cpus as static prediction overrides processor dynamic
16603 prediction. For older cpus we may as well always hint, but
16604 assume not taken for branches that are very close to 50% as a
16605 mispredicted taken branch is more expensive than a
16606 mispredicted not-taken branch. */
16607 if (rs6000_always_hint
16608 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16609 && br_prob_note_reliable_p (note)))
16611 if (abs (prob) > REG_BR_PROB_BASE / 20
16612 && ((prob > 0) ^ need_longbranch))
16620 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16622 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16624 /* We need to escape any '%' characters in the reg_names string.
16625 Assume they'd only be the first character.... */
16626 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16628 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16632 /* If the branch distance was too far, we may have to use an
16633 unconditional branch to go the distance. */
16634 if (need_longbranch)
16635 s += sprintf (s, ",$+8\n\tb %s", label);
16637 s += sprintf (s, ",%s", label);
16643 /* Return the string to flip the GT bit on a CR. */
16645 output_e500_flip_gt_bit (rtx dst, rtx src)
16647 static char string[64];
16650 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16651 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16654 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16655 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16657 sprintf (string, "crnot %d,%d", a, b);
16661 /* Return insn for VSX or Altivec comparisons. */
16664 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16667 enum machine_mode mode = GET_MODE (op0);
16675 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16681 mask = gen_reg_rtx (mode);
16682 emit_insn (gen_rtx_SET (VOIDmode,
16684 gen_rtx_fmt_ee (code, mode, op0, op1)));
16691 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16692 DMODE is expected destination mode. This is a recursive function. */
16695 rs6000_emit_vector_compare (enum rtx_code rcode,
16697 enum machine_mode dmode)
16700 bool swap_operands = false;
16701 bool try_again = false;
16703 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16704 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16706 /* See if the comparison works as is. */
16707 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16715 swap_operands = true;
16720 swap_operands = true;
16728 /* Invert condition and try again.
16729 e.g., A != B becomes ~(A==B). */
16731 enum rtx_code rev_code;
16732 enum insn_code nor_code;
16735 rev_code = reverse_condition_maybe_unordered (rcode);
16736 if (rev_code == UNKNOWN)
16739 nor_code = optab_handler (one_cmpl_optab, dmode);
16740 if (nor_code == CODE_FOR_nothing)
16743 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16747 mask = gen_reg_rtx (dmode);
16748 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16756 /* Try GT/GTU/LT/LTU OR EQ */
16759 enum insn_code ior_code;
16760 enum rtx_code new_code;
16781 gcc_unreachable ();
16784 ior_code = optab_handler (ior_optab, dmode);
16785 if (ior_code == CODE_FOR_nothing)
16788 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16792 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16796 mask = gen_reg_rtx (dmode);
16797 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16815 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16820 /* You only get two chances. */
16824 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16825 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16826 operands for the relation operation COND. */
16829 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16830 rtx cond, rtx cc_op0, rtx cc_op1)
16832 enum machine_mode dest_mode = GET_MODE (dest);
16833 enum rtx_code rcode = GET_CODE (cond);
16834 enum machine_mode cc_mode = CCmode;
16838 bool invert_move = false;
16840 if (VECTOR_UNIT_NONE_P (dest_mode))
16845 /* Swap operands if we can, and fall back to doing the operation as
16846 specified, and doing a NOR to invert the test. */
16852 /* Invert condition and try again.
16853 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16854 invert_move = true;
16855 rcode = reverse_condition_maybe_unordered (rcode);
16856 if (rcode == UNKNOWN)
16860 /* Mark unsigned tests with CCUNSmode. */
16865 cc_mode = CCUNSmode;
16872 /* Get the vector mask for the given relational operations. */
16873 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16881 op_true = op_false;
16885 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, CONST0_RTX (dest_mode));
16886 emit_insn (gen_rtx_SET (VOIDmode,
16888 gen_rtx_IF_THEN_ELSE (dest_mode,
16895 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16896 operands of the last comparison is nonzero/true, FALSE_COND if it
16897 is zero/false. Return 0 if the hardware has no such operation. */
16900 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16902 enum rtx_code code = GET_CODE (op);
16903 rtx op0 = XEXP (op, 0);
16904 rtx op1 = XEXP (op, 1);
16905 REAL_VALUE_TYPE c1;
16906 enum machine_mode compare_mode = GET_MODE (op0);
16907 enum machine_mode result_mode = GET_MODE (dest);
16909 bool is_against_zero;
16911 /* These modes should always match. */
16912 if (GET_MODE (op1) != compare_mode
16913 /* In the isel case however, we can use a compare immediate, so
16914 op1 may be a small constant. */
16915 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16917 if (GET_MODE (true_cond) != result_mode)
16919 if (GET_MODE (false_cond) != result_mode)
16922 /* First, work out if the hardware can do this at all, or
16923 if it's too slow.... */
16924 if (!FLOAT_MODE_P (compare_mode))
16927 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16930 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16931 && SCALAR_FLOAT_MODE_P (compare_mode))
16934 is_against_zero = op1 == CONST0_RTX (compare_mode);
16936 /* A floating-point subtract might overflow, underflow, or produce
16937 an inexact result, thus changing the floating-point flags, so it
16938 can't be generated if we care about that. It's safe if one side
16939 of the construct is zero, since then no subtract will be
16941 if (SCALAR_FLOAT_MODE_P (compare_mode)
16942 && flag_trapping_math && ! is_against_zero)
16945 /* Eliminate half of the comparisons by switching operands, this
16946 makes the remaining code simpler. */
16947 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16948 || code == LTGT || code == LT || code == UNLE)
16950 code = reverse_condition_maybe_unordered (code);
16952 true_cond = false_cond;
16956 /* UNEQ and LTGT take four instructions for a comparison with zero,
16957 it'll probably be faster to use a branch here too. */
16958 if (code == UNEQ && HONOR_NANS (compare_mode))
16961 if (GET_CODE (op1) == CONST_DOUBLE)
16962 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16964 /* We're going to try to implement comparisons by performing
16965 a subtract, then comparing against zero. Unfortunately,
16966 Inf - Inf is NaN which is not zero, and so if we don't
16967 know that the operand is finite and the comparison
16968 would treat EQ different to UNORDERED, we can't do it. */
16969 if (HONOR_INFINITIES (compare_mode)
16970 && code != GT && code != UNGE
16971 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16972 /* Constructs of the form (a OP b ? a : b) are safe. */
16973 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16974 || (! rtx_equal_p (op0, true_cond)
16975 && ! rtx_equal_p (op1, true_cond))))
16978 /* At this point we know we can use fsel. */
16980 /* Reduce the comparison to a comparison against zero. */
16981 if (! is_against_zero)
16983 temp = gen_reg_rtx (compare_mode);
16984 emit_insn (gen_rtx_SET (VOIDmode, temp,
16985 gen_rtx_MINUS (compare_mode, op0, op1)));
16987 op1 = CONST0_RTX (compare_mode);
16990 /* If we don't care about NaNs we can reduce some of the comparisons
16991 down to faster ones. */
16992 if (! HONOR_NANS (compare_mode))
16998 true_cond = false_cond;
17011 /* Now, reduce everything down to a GE. */
17018 temp = gen_reg_rtx (compare_mode);
17019 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17024 temp = gen_reg_rtx (compare_mode);
17025 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17030 temp = gen_reg_rtx (compare_mode);
17031 emit_insn (gen_rtx_SET (VOIDmode, temp,
17032 gen_rtx_NEG (compare_mode,
17033 gen_rtx_ABS (compare_mode, op0))));
17038 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17039 temp = gen_reg_rtx (result_mode);
17040 emit_insn (gen_rtx_SET (VOIDmode, temp,
17041 gen_rtx_IF_THEN_ELSE (result_mode,
17042 gen_rtx_GE (VOIDmode,
17044 true_cond, false_cond)));
17045 false_cond = true_cond;
17048 temp = gen_reg_rtx (compare_mode);
17049 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17054 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17055 temp = gen_reg_rtx (result_mode);
17056 emit_insn (gen_rtx_SET (VOIDmode, temp,
17057 gen_rtx_IF_THEN_ELSE (result_mode,
17058 gen_rtx_GE (VOIDmode,
17060 true_cond, false_cond)));
17061 true_cond = false_cond;
17064 temp = gen_reg_rtx (compare_mode);
17065 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17070 gcc_unreachable ();
17073 emit_insn (gen_rtx_SET (VOIDmode, dest,
17074 gen_rtx_IF_THEN_ELSE (result_mode,
17075 gen_rtx_GE (VOIDmode,
17077 true_cond, false_cond)));
17081 /* Same as above, but for ints (isel). */
17084 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17086 rtx condition_rtx, cr;
17087 enum machine_mode mode = GET_MODE (dest);
17088 enum rtx_code cond_code;
17089 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17092 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17095 /* We still have to do the compare, because isel doesn't do a
17096 compare, it just looks at the CRx bits set by a previous compare
17098 condition_rtx = rs6000_generate_compare (op, mode);
17099 cond_code = GET_CODE (condition_rtx);
17100 cr = XEXP (condition_rtx, 0);
17101 signedp = GET_MODE (cr) == CCmode;
17103 isel_func = (mode == SImode
17104 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17105 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17109 case LT: case GT: case LTU: case GTU: case EQ:
17110 /* isel handles these directly. */
17114 /* We need to swap the sense of the comparison. */
17117 true_cond = false_cond;
17119 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17124 false_cond = force_reg (mode, false_cond);
17125 if (true_cond != const0_rtx)
17126 true_cond = force_reg (mode, true_cond);
17128 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17134 output_isel (rtx *operands)
17136 enum rtx_code code;
17138 code = GET_CODE (operands[1]);
17140 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17142 gcc_assert (GET_CODE (operands[2]) == REG
17143 && GET_CODE (operands[3]) == REG);
17144 PUT_CODE (operands[1], reverse_condition (code));
17145 return "isel %0,%3,%2,%j1";
17148 return "isel %0,%2,%3,%j1";
17152 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17154 enum machine_mode mode = GET_MODE (op0);
17158 /* VSX/altivec have direct min/max insns. */
17159 if ((code == SMAX || code == SMIN)
17160 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17161 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17163 emit_insn (gen_rtx_SET (VOIDmode,
17165 gen_rtx_fmt_ee (code, mode, op0, op1)));
17169 if (code == SMAX || code == SMIN)
17174 if (code == SMAX || code == UMAX)
17175 target = emit_conditional_move (dest, c, op0, op1, mode,
17176 op0, op1, mode, 0);
17178 target = emit_conditional_move (dest, c, op0, op1, mode,
17179 op1, op0, mode, 0);
17180 gcc_assert (target);
17181 if (target != dest)
17182 emit_move_insn (dest, target);
17185 /* Emit instructions to perform a load-reserved/store-conditional operation.
17186 The operation performed is an atomic
17187 (set M (CODE:MODE M OP))
17188 If not NULL, BEFORE is atomically set to M before the operation, and
17189 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17190 If SYNC_P then a memory barrier is emitted before the operation.
17191 Either OP or M may be wrapped in a NOT operation. */
17194 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17195 rtx m, rtx op, rtx before_param, rtx after_param,
17198 enum machine_mode used_mode;
17199 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17202 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17203 rtx shift = NULL_RTX;
17206 emit_insn (gen_lwsync ());
17210 /* If this is smaller than SImode, we'll have to use SImode with
17212 if (mode == QImode || mode == HImode)
17216 if (MEM_ALIGN (used_m) >= 32)
17219 if (BYTES_BIG_ENDIAN)
17220 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17222 shift = GEN_INT (ishift);
17223 used_m = change_address (used_m, SImode, 0);
17227 rtx addrSI, aligned_addr;
17228 int shift_mask = mode == QImode ? 0x18 : 0x10;
17230 addrSI = gen_lowpart_common (SImode,
17231 force_reg (Pmode, XEXP (used_m, 0)));
17232 addrSI = force_reg (SImode, addrSI);
17233 shift = gen_reg_rtx (SImode);
17235 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17236 GEN_INT (shift_mask)));
17237 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17239 aligned_addr = expand_binop (Pmode, and_optab,
17241 GEN_INT (-4), NULL_RTX,
17242 1, OPTAB_LIB_WIDEN);
17243 used_m = change_address (used_m, SImode, aligned_addr);
17244 set_mem_align (used_m, 32);
17246 /* It's safe to keep the old alias set of USED_M, because
17247 the operation is atomic and only affects the original
17251 if (GET_CODE (op) == NOT)
17253 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17254 oldop = gen_rtx_NOT (SImode, oldop);
17257 oldop = lowpart_subreg (SImode, op, mode);
17263 newop = expand_binop (SImode, and_optab,
17264 oldop, GEN_INT (imask), NULL_RTX,
17265 1, OPTAB_LIB_WIDEN);
17266 emit_insn (gen_ashlsi3 (newop, newop, shift));
17269 case NOT: /* NAND */
17270 newop = expand_binop (SImode, ior_optab,
17271 oldop, GEN_INT (~imask), NULL_RTX,
17272 1, OPTAB_LIB_WIDEN);
17273 emit_insn (gen_rotlsi3 (newop, newop, shift));
17277 newop = expand_binop (SImode, ior_optab,
17278 oldop, GEN_INT (~imask), NULL_RTX,
17279 1, OPTAB_LIB_WIDEN);
17280 emit_insn (gen_rotlsi3 (newop, newop, shift));
17288 newop = expand_binop (SImode, and_optab,
17289 oldop, GEN_INT (imask), NULL_RTX,
17290 1, OPTAB_LIB_WIDEN);
17291 emit_insn (gen_ashlsi3 (newop, newop, shift));
17293 mask = gen_reg_rtx (SImode);
17294 emit_move_insn (mask, GEN_INT (imask));
17295 emit_insn (gen_ashlsi3 (mask, mask, shift));
17298 newop = gen_rtx_PLUS (SImode, m, newop);
17300 newop = gen_rtx_MINUS (SImode, m, newop);
17301 newop = gen_rtx_AND (SImode, newop, mask);
17302 newop = gen_rtx_IOR (SImode, newop,
17303 gen_rtx_AND (SImode,
17304 gen_rtx_NOT (SImode, mask),
17310 gcc_unreachable ();
17314 used_mode = SImode;
17315 before = gen_reg_rtx (used_mode);
17316 after = gen_reg_rtx (used_mode);
17321 before = before_param;
17322 after = after_param;
17324 if (before == NULL_RTX)
17325 before = gen_reg_rtx (used_mode);
17326 if (after == NULL_RTX)
17327 after = gen_reg_rtx (used_mode);
17330 if ((code == PLUS || code == MINUS)
17331 && used_mode != mode)
17332 the_op = op; /* Computed above. */
17333 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17334 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17335 else if (code == NOT)
17336 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17337 gen_rtx_NOT (used_mode, m),
17338 gen_rtx_NOT (used_mode, op));
17340 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17342 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17343 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17344 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17345 gen_rtx_UNSPEC (used_mode,
17346 gen_rtvec (1, the_op),
17348 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17350 if ((code == PLUS || code == MINUS) && used_mode != mode)
17351 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17352 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17354 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17355 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17357 /* Shift and mask the return values properly. */
17358 if (used_mode != mode && before_param)
17360 emit_insn (gen_lshrsi3 (before, before, shift));
17361 convert_move (before_param, before, 1);
17364 if (used_mode != mode && after_param)
17366 emit_insn (gen_lshrsi3 (after, after, shift));
17367 convert_move (after_param, after, 1);
17370 /* The previous sequence will end with a branch that's dependent on
17371 the conditional store, so placing an isync will ensure that no
17372 other instructions (especially, no load or store instructions)
17373 can start before the atomic operation completes. */
17375 emit_insn (gen_isync ());
17378 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17379 COND is true. Mark the jump as unlikely to be taken. */
17382 emit_unlikely_jump (rtx cond, rtx label)
17384 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17387 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17388 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17389 add_reg_note (x, REG_BR_PROB, very_unlikely);
17392 /* A subroutine of the atomic operation splitters. Emit a load-locked
17393 instruction in MODE. */
17396 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17398 rtx (*fn) (rtx, rtx) = NULL;
17399 if (mode == SImode)
17400 fn = gen_load_locked_si;
17401 else if (mode == DImode)
17402 fn = gen_load_locked_di;
17403 emit_insn (fn (reg, mem));
17406 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17407 instruction in MODE. */
17410 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17412 rtx (*fn) (rtx, rtx, rtx) = NULL;
17413 if (mode == SImode)
17414 fn = gen_store_conditional_si;
17415 else if (mode == DImode)
17416 fn = gen_store_conditional_di;
17418 /* Emit sync before stwcx. to address PPC405 Erratum. */
17419 if (PPC405_ERRATUM77)
17420 emit_insn (gen_memory_barrier ());
17422 emit_insn (fn (res, mem, val));
17425 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17426 to perform. MEM is the memory on which to operate. VAL is the second
17427 operand of the binary operator. BEFORE and AFTER are optional locations to
17428 return the value of MEM either before of after the operation. SCRATCH is
17429 a scratch register. */
17432 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17433 rtx before, rtx after, rtx scratch)
17435 enum machine_mode mode = GET_MODE (mem);
17436 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17438 emit_insn (gen_lwsync ());
17440 label = gen_label_rtx ();
17441 emit_label (label);
17442 label = gen_rtx_LABEL_REF (VOIDmode, label);
17444 if (before == NULL_RTX)
17446 emit_load_locked (mode, before, mem);
17449 x = gen_rtx_IOR (mode,
17450 gen_rtx_NOT (mode, before),
17451 gen_rtx_NOT (mode, val));
17452 else if (code == AND)
17453 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17455 x = gen_rtx_fmt_ee (code, mode, before, val);
17457 if (after != NULL_RTX)
17458 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17459 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17461 emit_store_conditional (mode, cond, mem, scratch);
17463 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17464 emit_unlikely_jump (x, label);
17466 emit_insn (gen_isync ());
17469 /* Expand an atomic compare and swap operation. MEM is the memory on which
17470 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17471 value to be stored. SCRATCH is a scratch GPR. */
17474 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17477 enum machine_mode mode = GET_MODE (mem);
17478 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17480 emit_insn (gen_lwsync ());
17482 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17483 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17484 emit_label (XEXP (label1, 0));
17486 emit_load_locked (mode, retval, mem);
17488 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17489 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17491 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17492 emit_unlikely_jump (x, label2);
17494 emit_move_insn (scratch, newval);
17495 emit_store_conditional (mode, cond, mem, scratch);
17497 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17498 emit_unlikely_jump (x, label1);
17500 emit_insn (gen_isync ());
17501 emit_label (XEXP (label2, 0));
17504 /* Expand an atomic test and set operation. MEM is the memory on which
17505 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17508 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17510 enum machine_mode mode = GET_MODE (mem);
17511 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17513 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17514 emit_label (XEXP (label, 0));
17516 emit_load_locked (mode, retval, mem);
17517 emit_move_insn (scratch, val);
17518 emit_store_conditional (mode, cond, mem, scratch);
17520 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17521 emit_unlikely_jump (x, label);
17523 emit_insn (gen_isync ());
17527 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17529 enum machine_mode mode = GET_MODE (mem);
17530 rtx addrSI, align, wdst, shift, mask;
17531 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17532 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17534 /* Shift amount for subword relative to aligned word. */
17535 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17536 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17537 shift = gen_reg_rtx (SImode);
17538 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17539 GEN_INT (shift_mask)));
17540 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17542 /* Shift and mask old value into position within word. */
17543 oldval = convert_modes (SImode, mode, oldval, 1);
17544 oldval = expand_binop (SImode, and_optab,
17545 oldval, GEN_INT (imask), NULL_RTX,
17546 1, OPTAB_LIB_WIDEN);
17547 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17549 /* Shift and mask new value into position within word. */
17550 newval = convert_modes (SImode, mode, newval, 1);
17551 newval = expand_binop (SImode, and_optab,
17552 newval, GEN_INT (imask), NULL_RTX,
17553 1, OPTAB_LIB_WIDEN);
17554 emit_insn (gen_ashlsi3 (newval, newval, shift));
17556 /* Mask for insertion. */
17557 mask = gen_reg_rtx (SImode);
17558 emit_move_insn (mask, GEN_INT (imask));
17559 emit_insn (gen_ashlsi3 (mask, mask, shift));
17561 /* Address of aligned word containing subword. */
17562 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17563 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17564 mem = change_address (mem, SImode, align);
17565 set_mem_align (mem, 32);
17566 MEM_VOLATILE_P (mem) = 1;
17568 wdst = gen_reg_rtx (SImode);
17569 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17570 oldval, newval, mem));
17572 /* Shift the result back. */
17573 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17575 emit_move_insn (dst, gen_lowpart (mode, wdst));
17579 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17580 rtx oldval, rtx newval, rtx mem,
17583 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17585 emit_insn (gen_lwsync ());
17586 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17587 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17588 emit_label (XEXP (label1, 0));
17590 emit_load_locked (SImode, scratch, mem);
17592 /* Mask subword within loaded value for comparison with oldval.
17593 Use UNSPEC_AND to avoid clobber.*/
17594 emit_insn (gen_rtx_SET (SImode, dest,
17595 gen_rtx_UNSPEC (SImode,
17596 gen_rtvec (2, scratch, mask),
17599 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17600 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17602 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17603 emit_unlikely_jump (x, label2);
17605 /* Clear subword within loaded value for insertion of new value. */
17606 emit_insn (gen_rtx_SET (SImode, scratch,
17607 gen_rtx_AND (SImode,
17608 gen_rtx_NOT (SImode, mask), scratch)));
17609 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17610 emit_store_conditional (SImode, cond, mem, scratch);
17612 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17613 emit_unlikely_jump (x, label1);
17615 emit_insn (gen_isync ());
17616 emit_label (XEXP (label2, 0));
17620 /* Emit instructions to move SRC to DST. Called by splitters for
17621 multi-register moves. It will emit at most one instruction for
17622 each register that is accessed; that is, it won't emit li/lis pairs
17623 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17627 rs6000_split_multireg_move (rtx dst, rtx src)
17629 /* The register number of the first register being moved. */
17631 /* The mode that is to be moved. */
17632 enum machine_mode mode;
17633 /* The mode that the move is being done in, and its size. */
17634 enum machine_mode reg_mode;
17636 /* The number of registers that will be moved. */
17639 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17640 mode = GET_MODE (dst);
17641 nregs = hard_regno_nregs[reg][mode];
17642 if (FP_REGNO_P (reg))
17643 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17644 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17645 else if (ALTIVEC_REGNO_P (reg))
17646 reg_mode = V16QImode;
17647 else if (TARGET_E500_DOUBLE && mode == TFmode)
17650 reg_mode = word_mode;
17651 reg_mode_size = GET_MODE_SIZE (reg_mode);
17653 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17655 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17657 /* Move register range backwards, if we might have destructive
17660 for (i = nregs - 1; i >= 0; i--)
17661 emit_insn (gen_rtx_SET (VOIDmode,
17662 simplify_gen_subreg (reg_mode, dst, mode,
17663 i * reg_mode_size),
17664 simplify_gen_subreg (reg_mode, src, mode,
17665 i * reg_mode_size)));
17671 bool used_update = false;
17672 rtx restore_basereg = NULL_RTX;
17674 if (MEM_P (src) && INT_REGNO_P (reg))
17678 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17679 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17682 breg = XEXP (XEXP (src, 0), 0);
17683 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17684 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17685 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17686 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17687 src = replace_equiv_address (src, breg);
17689 else if (! rs6000_offsettable_memref_p (src))
17691 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17693 rtx basereg = XEXP (XEXP (src, 0), 0);
17696 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17697 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17698 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17699 used_update = true;
17702 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17703 XEXP (XEXP (src, 0), 1)));
17704 src = replace_equiv_address (src, basereg);
17708 rtx basereg = gen_rtx_REG (Pmode, reg);
17709 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17710 src = replace_equiv_address (src, basereg);
17714 breg = XEXP (src, 0);
17715 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17716 breg = XEXP (breg, 0);
17718 /* If the base register we are using to address memory is
17719 also a destination reg, then change that register last. */
17721 && REGNO (breg) >= REGNO (dst)
17722 && REGNO (breg) < REGNO (dst) + nregs)
17723 j = REGNO (breg) - REGNO (dst);
17725 else if (MEM_P (dst) && INT_REGNO_P (reg))
17729 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17730 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17733 breg = XEXP (XEXP (dst, 0), 0);
17734 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17735 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17736 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17738 /* We have to update the breg before doing the store.
17739 Use store with update, if available. */
17743 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17744 emit_insn (TARGET_32BIT
17745 ? (TARGET_POWERPC64
17746 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17747 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17748 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17749 used_update = true;
17752 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17753 dst = replace_equiv_address (dst, breg);
17755 else if (!rs6000_offsettable_memref_p (dst)
17756 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17758 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17760 rtx basereg = XEXP (XEXP (dst, 0), 0);
17763 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17764 emit_insn (gen_rtx_SET (VOIDmode,
17765 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17766 used_update = true;
17769 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17770 XEXP (XEXP (dst, 0), 1)));
17771 dst = replace_equiv_address (dst, basereg);
17775 rtx basereg = XEXP (XEXP (dst, 0), 0);
17776 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17777 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17779 && REG_P (offsetreg)
17780 && REGNO (basereg) != REGNO (offsetreg));
17781 if (REGNO (basereg) == 0)
17783 rtx tmp = offsetreg;
17784 offsetreg = basereg;
17787 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17788 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17789 dst = replace_equiv_address (dst, basereg);
17792 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17793 gcc_assert (rs6000_offsettable_memref_p (dst));
17796 for (i = 0; i < nregs; i++)
17798 /* Calculate index to next subword. */
17803 /* If compiler already emitted move of first word by
17804 store with update, no need to do anything. */
17805 if (j == 0 && used_update)
17808 emit_insn (gen_rtx_SET (VOIDmode,
17809 simplify_gen_subreg (reg_mode, dst, mode,
17810 j * reg_mode_size),
17811 simplify_gen_subreg (reg_mode, src, mode,
17812 j * reg_mode_size)));
17814 if (restore_basereg != NULL_RTX)
17815 emit_insn (restore_basereg);
17820 /* This page contains routines that are used to determine what the
17821 function prologue and epilogue code will do and write them out. */
17823 /* Return the first fixed-point register that is required to be
17824 saved. 32 if none. */
17827 first_reg_to_save (void)
17831 /* Find lowest numbered live register. */
17832 for (first_reg = 13; first_reg <= 31; first_reg++)
17833 if (df_regs_ever_live_p (first_reg)
17834 && (! call_used_regs[first_reg]
17835 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17836 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17837 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17838 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17843 && crtl->uses_pic_offset_table
17844 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17845 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17851 /* Similar, for FP regs. */
17854 first_fp_reg_to_save (void)
17858 /* Find lowest numbered live register. */
17859 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17860 if (df_regs_ever_live_p (first_reg))
17866 /* Similar, for AltiVec regs. */
17869 first_altivec_reg_to_save (void)
17873 /* Stack frame remains as is unless we are in AltiVec ABI. */
17874 if (! TARGET_ALTIVEC_ABI)
17875 return LAST_ALTIVEC_REGNO + 1;
17877 /* On Darwin, the unwind routines are compiled without
17878 TARGET_ALTIVEC, and use save_world to save/restore the
17879 altivec registers when necessary. */
17880 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17881 && ! TARGET_ALTIVEC)
17882 return FIRST_ALTIVEC_REGNO + 20;
17884 /* Find lowest numbered live register. */
17885 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17886 if (df_regs_ever_live_p (i))
17892 /* Return a 32-bit mask of the AltiVec registers we need to set in
17893 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17894 the 32-bit word is 0. */
17896 static unsigned int
17897 compute_vrsave_mask (void)
17899 unsigned int i, mask = 0;
17901 /* On Darwin, the unwind routines are compiled without
17902 TARGET_ALTIVEC, and use save_world to save/restore the
17903 call-saved altivec registers when necessary. */
17904 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17905 && ! TARGET_ALTIVEC)
17908 /* First, find out if we use _any_ altivec registers. */
17909 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17910 if (df_regs_ever_live_p (i))
17911 mask |= ALTIVEC_REG_BIT (i);
17916 /* Next, remove the argument registers from the set. These must
17917 be in the VRSAVE mask set by the caller, so we don't need to add
17918 them in again. More importantly, the mask we compute here is
17919 used to generate CLOBBERs in the set_vrsave insn, and we do not
17920 wish the argument registers to die. */
17921 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17922 mask &= ~ALTIVEC_REG_BIT (i);
17924 /* Similarly, remove the return value from the set. */
17927 diddle_return_value (is_altivec_return_reg, &yes);
17929 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17935 /* For a very restricted set of circumstances, we can cut down the
17936 size of prologues/epilogues by calling our own save/restore-the-world
17940 compute_save_world_info (rs6000_stack_t *info_ptr)
17942 info_ptr->world_save_p = 1;
17943 info_ptr->world_save_p
17944 = (WORLD_SAVE_P (info_ptr)
17945 && DEFAULT_ABI == ABI_DARWIN
17946 && ! (cfun->calls_setjmp && flag_exceptions)
17947 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17948 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17949 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17950 && info_ptr->cr_save_p);
17952 /* This will not work in conjunction with sibcalls. Make sure there
17953 are none. (This check is expensive, but seldom executed.) */
17954 if (WORLD_SAVE_P (info_ptr))
17957 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17958 if ( GET_CODE (insn) == CALL_INSN
17959 && SIBLING_CALL_P (insn))
17961 info_ptr->world_save_p = 0;
17966 if (WORLD_SAVE_P (info_ptr))
17968 /* Even if we're not touching VRsave, make sure there's room on the
17969 stack for it, if it looks like we're calling SAVE_WORLD, which
17970 will attempt to save it. */
17971 info_ptr->vrsave_size = 4;
17973 /* If we are going to save the world, we need to save the link register too. */
17974 info_ptr->lr_save_p = 1;
17976 /* "Save" the VRsave register too if we're saving the world. */
17977 if (info_ptr->vrsave_mask == 0)
17978 info_ptr->vrsave_mask = compute_vrsave_mask ();
17980 /* Because the Darwin register save/restore routines only handle
17981 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17983 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17984 && (info_ptr->first_altivec_reg_save
17985 >= FIRST_SAVED_ALTIVEC_REGNO));
17992 is_altivec_return_reg (rtx reg, void *xyes)
17994 bool *yes = (bool *) xyes;
17995 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18000 /* Determine the strategy for savings/restoring registers. */
18003 SAVRES_MULTIPLE = 0x1,
18004 SAVE_INLINE_FPRS = 0x2,
18005 SAVE_INLINE_GPRS = 0x4,
18006 REST_INLINE_FPRS = 0x8,
18007 REST_INLINE_GPRS = 0x10,
18008 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18009 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18010 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18014 rs6000_savres_strategy (rs6000_stack_t *info,
18015 bool using_static_chain_p)
18019 if (TARGET_MULTIPLE
18020 && !TARGET_POWERPC64
18021 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18022 && info->first_gp_reg_save < 31
18023 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18024 strategy |= SAVRES_MULTIPLE;
18026 if (crtl->calls_eh_return
18027 || cfun->machine->ra_need_lr
18028 || info->total_size > 32767)
18029 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18030 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18032 if (info->first_fp_reg_save == 64
18033 || FP_SAVE_INLINE (info->first_fp_reg_save)
18034 /* The out-of-line FP routines use double-precision stores;
18035 we can't use those routines if we don't have such stores. */
18036 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18037 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18038 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18040 if (info->first_gp_reg_save == 32
18041 || GP_SAVE_INLINE (info->first_gp_reg_save)
18042 || !((strategy & SAVRES_MULTIPLE)
18043 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18044 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18046 /* Don't bother to try to save things out-of-line if r11 is occupied
18047 by the static chain. It would require too much fiddling and the
18048 static chain is rarely used anyway. */
18049 if (using_static_chain_p)
18050 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18052 /* If we are going to use store multiple, then don't even bother
18053 with the out-of-line routines, since the store-multiple
18054 instruction will always be smaller. */
18055 if ((strategy & SAVRES_MULTIPLE))
18056 strategy |= SAVE_INLINE_GPRS;
18058 /* The situation is more complicated with load multiple. We'd
18059 prefer to use the out-of-line routines for restores, since the
18060 "exit" out-of-line routines can handle the restore of LR and the
18061 frame teardown. However if doesn't make sense to use the
18062 out-of-line routine if that is the only reason we'd need to save
18063 LR, and we can't use the "exit" out-of-line gpr restore if we
18064 have saved some fprs; In those cases it is advantageous to use
18065 load multiple when available. */
18066 if ((strategy & SAVRES_MULTIPLE)
18067 && (!info->lr_save_p
18068 || info->first_fp_reg_save != 64))
18069 strategy |= REST_INLINE_GPRS;
18071 /* We can only use load multiple or the out-of-line routines to
18072 restore if we've used store multiple or out-of-line routines
18073 in the prologue, i.e. if we've saved all the registers from
18074 first_gp_reg_save. Otherwise, we risk loading garbage. */
18075 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18076 strategy |= REST_INLINE_GPRS;
18078 /* Saving CR interferes with the exit routines used on the SPE, so
18081 && info->spe_64bit_regs_used
18082 && info->cr_save_p)
18083 strategy |= REST_INLINE_GPRS;
18085 #ifdef POWERPC_LINUX
18088 if (!(strategy & SAVE_INLINE_FPRS))
18089 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18090 else if (!(strategy & SAVE_INLINE_GPRS)
18091 && info->first_fp_reg_save == 64)
18092 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18095 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18096 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18101 /* Calculate the stack information for the current function. This is
18102 complicated by having two separate calling sequences, the AIX calling
18103 sequence and the V.4 calling sequence.
18105 AIX (and Darwin/Mac OS X) stack frames look like:
18107 SP----> +---------------------------------------+
18108 | back chain to caller | 0 0
18109 +---------------------------------------+
18110 | saved CR | 4 8 (8-11)
18111 +---------------------------------------+
18113 +---------------------------------------+
18114 | reserved for compilers | 12 24
18115 +---------------------------------------+
18116 | reserved for binders | 16 32
18117 +---------------------------------------+
18118 | saved TOC pointer | 20 40
18119 +---------------------------------------+
18120 | Parameter save area (P) | 24 48
18121 +---------------------------------------+
18122 | Alloca space (A) | 24+P etc.
18123 +---------------------------------------+
18124 | Local variable space (L) | 24+P+A
18125 +---------------------------------------+
18126 | Float/int conversion temporary (X) | 24+P+A+L
18127 +---------------------------------------+
18128 | Save area for AltiVec registers (W) | 24+P+A+L+X
18129 +---------------------------------------+
18130 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18131 +---------------------------------------+
18132 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18133 +---------------------------------------+
18134 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18135 +---------------------------------------+
18136 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18137 +---------------------------------------+
18138 old SP->| back chain to caller's caller |
18139 +---------------------------------------+
18141 The required alignment for AIX configurations is two words (i.e., 8
18145 V.4 stack frames look like:
18147 SP----> +---------------------------------------+
18148 | back chain to caller | 0
18149 +---------------------------------------+
18150 | caller's saved LR | 4
18151 +---------------------------------------+
18152 | Parameter save area (P) | 8
18153 +---------------------------------------+
18154 | Alloca space (A) | 8+P
18155 +---------------------------------------+
18156 | Varargs save area (V) | 8+P+A
18157 +---------------------------------------+
18158 | Local variable space (L) | 8+P+A+V
18159 +---------------------------------------+
18160 | Float/int conversion temporary (X) | 8+P+A+V+L
18161 +---------------------------------------+
18162 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18163 +---------------------------------------+
18164 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18165 +---------------------------------------+
18166 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18167 +---------------------------------------+
18168 | SPE: area for 64-bit GP registers |
18169 +---------------------------------------+
18170 | SPE alignment padding |
18171 +---------------------------------------+
18172 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18173 +---------------------------------------+
18174 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18175 +---------------------------------------+
18176 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18177 +---------------------------------------+
18178 old SP->| back chain to caller's caller |
18179 +---------------------------------------+
18181 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18182 given. (But note below and in sysv4.h that we require only 8 and
18183 may round up the size of our stack frame anyways. The historical
18184 reason is early versions of powerpc-linux which didn't properly
18185 align the stack at program startup. A happy side-effect is that
18186 -mno-eabi libraries can be used with -meabi programs.)
18188 The EABI configuration defaults to the V.4 layout. However,
18189 the stack alignment requirements may differ. If -mno-eabi is not
18190 given, the required stack alignment is 8 bytes; if -mno-eabi is
18191 given, the required alignment is 16 bytes. (But see V.4 comment
18194 #ifndef ABI_STACK_BOUNDARY
18195 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18198 static rs6000_stack_t *
18199 rs6000_stack_info (void)
18201 rs6000_stack_t *info_ptr = &stack_info;
18202 int reg_size = TARGET_32BIT ? 4 : 8;
18206 HOST_WIDE_INT non_fixed_size;
18207 bool using_static_chain_p;
18209 if (reload_completed && info_ptr->reload_completed)
18212 memset (info_ptr, 0, sizeof (*info_ptr));
18213 info_ptr->reload_completed = reload_completed;
18217 /* Cache value so we don't rescan instruction chain over and over. */
18218 if (cfun->machine->insn_chain_scanned_p == 0)
18219 cfun->machine->insn_chain_scanned_p
18220 = spe_func_has_64bit_regs_p () + 1;
18221 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18224 /* Select which calling sequence. */
18225 info_ptr->abi = DEFAULT_ABI;
18227 /* Calculate which registers need to be saved & save area size. */
18228 info_ptr->first_gp_reg_save = first_reg_to_save ();
18229 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18230 even if it currently looks like we won't. Reload may need it to
18231 get at a constant; if so, it will have already created a constant
18232 pool entry for it. */
18233 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18234 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18235 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18236 && crtl->uses_const_pool
18237 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18238 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18240 first_gp = info_ptr->first_gp_reg_save;
18242 info_ptr->gp_size = reg_size * (32 - first_gp);
18244 /* For the SPE, we have an additional upper 32-bits on each GPR.
18245 Ideally we should save the entire 64-bits only when the upper
18246 half is used in SIMD instructions. Since we only record
18247 registers live (not the size they are used in), this proves
18248 difficult because we'd have to traverse the instruction chain at
18249 the right time, taking reload into account. This is a real pain,
18250 so we opt to save the GPRs in 64-bits always if but one register
18251 gets used in 64-bits. Otherwise, all the registers in the frame
18252 get saved in 32-bits.
18254 So... since when we save all GPRs (except the SP) in 64-bits, the
18255 traditional GP save area will be empty. */
18256 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18257 info_ptr->gp_size = 0;
18259 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18260 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18262 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18263 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18264 - info_ptr->first_altivec_reg_save);
18266 /* Does this function call anything? */
18267 info_ptr->calls_p = (! current_function_is_leaf
18268 || cfun->machine->ra_needs_full_frame);
18270 /* Determine if we need to save the condition code registers. */
18271 if (df_regs_ever_live_p (CR2_REGNO)
18272 || df_regs_ever_live_p (CR3_REGNO)
18273 || df_regs_ever_live_p (CR4_REGNO))
18275 info_ptr->cr_save_p = 1;
18276 if (DEFAULT_ABI == ABI_V4)
18277 info_ptr->cr_size = reg_size;
18280 /* If the current function calls __builtin_eh_return, then we need
18281 to allocate stack space for registers that will hold data for
18282 the exception handler. */
18283 if (crtl->calls_eh_return)
18286 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18289 /* SPE saves EH registers in 64-bits. */
18290 ehrd_size = i * (TARGET_SPE_ABI
18291 && info_ptr->spe_64bit_regs_used != 0
18292 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18297 /* Determine various sizes. */
18298 info_ptr->reg_size = reg_size;
18299 info_ptr->fixed_size = RS6000_SAVE_AREA;
18300 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18301 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18302 TARGET_ALTIVEC ? 16 : 8);
18303 if (FRAME_GROWS_DOWNWARD)
18304 info_ptr->vars_size
18305 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18306 + info_ptr->parm_size,
18307 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18308 - (info_ptr->fixed_size + info_ptr->vars_size
18309 + info_ptr->parm_size);
18311 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18312 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18314 info_ptr->spe_gp_size = 0;
18316 if (TARGET_ALTIVEC_ABI)
18317 info_ptr->vrsave_mask = compute_vrsave_mask ();
18319 info_ptr->vrsave_mask = 0;
18321 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18322 info_ptr->vrsave_size = 4;
18324 info_ptr->vrsave_size = 0;
18326 compute_save_world_info (info_ptr);
18328 /* Calculate the offsets. */
18329 switch (DEFAULT_ABI)
18333 gcc_unreachable ();
18337 info_ptr->fp_save_offset = - info_ptr->fp_size;
18338 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18340 if (TARGET_ALTIVEC_ABI)
18342 info_ptr->vrsave_save_offset
18343 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18345 /* Align stack so vector save area is on a quadword boundary.
18346 The padding goes above the vectors. */
18347 if (info_ptr->altivec_size != 0)
18348 info_ptr->altivec_padding_size
18349 = info_ptr->vrsave_save_offset & 0xF;
18351 info_ptr->altivec_padding_size = 0;
18353 info_ptr->altivec_save_offset
18354 = info_ptr->vrsave_save_offset
18355 - info_ptr->altivec_padding_size
18356 - info_ptr->altivec_size;
18357 gcc_assert (info_ptr->altivec_size == 0
18358 || info_ptr->altivec_save_offset % 16 == 0);
18360 /* Adjust for AltiVec case. */
18361 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18364 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18365 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18366 info_ptr->lr_save_offset = 2*reg_size;
18370 info_ptr->fp_save_offset = - info_ptr->fp_size;
18371 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18372 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18374 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18376 /* Align stack so SPE GPR save area is aligned on a
18377 double-word boundary. */
18378 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18379 info_ptr->spe_padding_size
18380 = 8 - (-info_ptr->cr_save_offset % 8);
18382 info_ptr->spe_padding_size = 0;
18384 info_ptr->spe_gp_save_offset
18385 = info_ptr->cr_save_offset
18386 - info_ptr->spe_padding_size
18387 - info_ptr->spe_gp_size;
18389 /* Adjust for SPE case. */
18390 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18392 else if (TARGET_ALTIVEC_ABI)
18394 info_ptr->vrsave_save_offset
18395 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18397 /* Align stack so vector save area is on a quadword boundary. */
18398 if (info_ptr->altivec_size != 0)
18399 info_ptr->altivec_padding_size
18400 = 16 - (-info_ptr->vrsave_save_offset % 16);
18402 info_ptr->altivec_padding_size = 0;
18404 info_ptr->altivec_save_offset
18405 = info_ptr->vrsave_save_offset
18406 - info_ptr->altivec_padding_size
18407 - info_ptr->altivec_size;
18409 /* Adjust for AltiVec case. */
18410 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18413 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18414 info_ptr->ehrd_offset -= ehrd_size;
18415 info_ptr->lr_save_offset = reg_size;
18419 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18420 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18421 + info_ptr->gp_size
18422 + info_ptr->altivec_size
18423 + info_ptr->altivec_padding_size
18424 + info_ptr->spe_gp_size
18425 + info_ptr->spe_padding_size
18427 + info_ptr->cr_size
18428 + info_ptr->vrsave_size,
18431 non_fixed_size = (info_ptr->vars_size
18432 + info_ptr->parm_size
18433 + info_ptr->save_size);
18435 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18436 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18438 /* Determine if we need to save the link register. */
18439 if (info_ptr->calls_p
18440 || (DEFAULT_ABI == ABI_AIX
18442 && !TARGET_PROFILE_KERNEL)
18443 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18444 #ifdef TARGET_RELOCATABLE
18445 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18447 || rs6000_ra_ever_killed ())
18448 info_ptr->lr_save_p = 1;
18450 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18451 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18452 && call_used_regs[STATIC_CHAIN_REGNUM]);
18453 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18454 using_static_chain_p);
18456 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18457 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18458 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18459 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18460 info_ptr->lr_save_p = 1;
18462 if (info_ptr->lr_save_p)
18463 df_set_regs_ever_live (LR_REGNO, true);
18465 /* Determine if we need to allocate any stack frame:
18467 For AIX we need to push the stack if a frame pointer is needed
18468 (because the stack might be dynamically adjusted), if we are
18469 debugging, if we make calls, or if the sum of fp_save, gp_save,
18470 and local variables are more than the space needed to save all
18471 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18472 + 18*8 = 288 (GPR13 reserved).
18474 For V.4 we don't have the stack cushion that AIX uses, but assume
18475 that the debugger can handle stackless frames. */
18477 if (info_ptr->calls_p)
18478 info_ptr->push_p = 1;
18480 else if (DEFAULT_ABI == ABI_V4)
18481 info_ptr->push_p = non_fixed_size != 0;
18483 else if (frame_pointer_needed)
18484 info_ptr->push_p = 1;
18486 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18487 info_ptr->push_p = 1;
18490 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18492 /* Zero offsets if we're not saving those registers. */
18493 if (info_ptr->fp_size == 0)
18494 info_ptr->fp_save_offset = 0;
18496 if (info_ptr->gp_size == 0)
18497 info_ptr->gp_save_offset = 0;
18499 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18500 info_ptr->altivec_save_offset = 0;
18502 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18503 info_ptr->vrsave_save_offset = 0;
18505 if (! TARGET_SPE_ABI
18506 || info_ptr->spe_64bit_regs_used == 0
18507 || info_ptr->spe_gp_size == 0)
18508 info_ptr->spe_gp_save_offset = 0;
18510 if (! info_ptr->lr_save_p)
18511 info_ptr->lr_save_offset = 0;
18513 if (! info_ptr->cr_save_p)
18514 info_ptr->cr_save_offset = 0;
18519 /* Return true if the current function uses any GPRs in 64-bit SIMD
18523 spe_func_has_64bit_regs_p (void)
18527 /* Functions that save and restore all the call-saved registers will
18528 need to save/restore the registers in 64-bits. */
18529 if (crtl->calls_eh_return
18530 || cfun->calls_setjmp
18531 || crtl->has_nonlocal_goto)
18534 insns = get_insns ();
18536 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18542 /* FIXME: This should be implemented with attributes...
18544 (set_attr "spe64" "true")....then,
18545 if (get_spe64(insn)) return true;
18547 It's the only reliable way to do the stuff below. */
18549 i = PATTERN (insn);
18550 if (GET_CODE (i) == SET)
18552 enum machine_mode mode = GET_MODE (SET_SRC (i));
18554 if (SPE_VECTOR_MODE (mode))
18556 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18566 debug_stack_info (rs6000_stack_t *info)
18568 const char *abi_string;
18571 info = rs6000_stack_info ();
18573 fprintf (stderr, "\nStack information for function %s:\n",
18574 ((current_function_decl && DECL_NAME (current_function_decl))
18575 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18580 default: abi_string = "Unknown"; break;
18581 case ABI_NONE: abi_string = "NONE"; break;
18582 case ABI_AIX: abi_string = "AIX"; break;
18583 case ABI_DARWIN: abi_string = "Darwin"; break;
18584 case ABI_V4: abi_string = "V.4"; break;
18587 fprintf (stderr, "\tABI = %5s\n", abi_string);
18589 if (TARGET_ALTIVEC_ABI)
18590 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18592 if (TARGET_SPE_ABI)
18593 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18595 if (info->first_gp_reg_save != 32)
18596 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18598 if (info->first_fp_reg_save != 64)
18599 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18601 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18602 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18603 info->first_altivec_reg_save);
18605 if (info->lr_save_p)
18606 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18608 if (info->cr_save_p)
18609 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18611 if (info->vrsave_mask)
18612 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18615 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18618 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18620 if (info->gp_save_offset)
18621 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18623 if (info->fp_save_offset)
18624 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18626 if (info->altivec_save_offset)
18627 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18628 info->altivec_save_offset);
18630 if (info->spe_gp_save_offset)
18631 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18632 info->spe_gp_save_offset);
18634 if (info->vrsave_save_offset)
18635 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18636 info->vrsave_save_offset);
18638 if (info->lr_save_offset)
18639 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18641 if (info->cr_save_offset)
18642 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18644 if (info->varargs_save_offset)
18645 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18647 if (info->total_size)
18648 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18651 if (info->vars_size)
18652 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18655 if (info->parm_size)
18656 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18658 if (info->fixed_size)
18659 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18662 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18664 if (info->spe_gp_size)
18665 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18668 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18670 if (info->altivec_size)
18671 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18673 if (info->vrsave_size)
18674 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18676 if (info->altivec_padding_size)
18677 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18678 info->altivec_padding_size);
18680 if (info->spe_padding_size)
18681 fprintf (stderr, "\tspe_padding_size = %5d\n",
18682 info->spe_padding_size);
18685 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18687 if (info->save_size)
18688 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18690 if (info->reg_size != 4)
18691 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18693 fprintf (stderr, "\n");
18697 rs6000_return_addr (int count, rtx frame)
18699 /* Currently we don't optimize very well between prolog and body
18700 code and for PIC code the code can be actually quite bad, so
18701 don't try to be too clever here. */
18702 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18704 cfun->machine->ra_needs_full_frame = 1;
18711 plus_constant (copy_to_reg
18712 (gen_rtx_MEM (Pmode,
18713 memory_address (Pmode, frame))),
18714 RETURN_ADDRESS_OFFSET)));
18717 cfun->machine->ra_need_lr = 1;
18718 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18721 /* Say whether a function is a candidate for sibcall handling or not. */
18724 rs6000_function_ok_for_sibcall (tree decl, tree exp)
18729 fntype = TREE_TYPE (decl);
18731 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
18733 /* We can't do it if the called function has more vector parameters
18734 than the current function; there's nowhere to put the VRsave code. */
18735 if (TARGET_ALTIVEC_ABI
18736 && TARGET_ALTIVEC_VRSAVE
18737 && !(decl && decl == current_function_decl))
18739 function_args_iterator args_iter;
18743 /* Functions with vector parameters are required to have a
18744 prototype, so the argument type info must be available
18746 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
18747 if (TREE_CODE (type) == VECTOR_TYPE
18748 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18751 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
18752 if (TREE_CODE (type) == VECTOR_TYPE
18753 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18760 /* Under the AIX ABI we can't allow calls to non-local functions,
18761 because the callee may have a different TOC pointer to the
18762 caller and there's no way to ensure we restore the TOC when we
18763 return. With the secure-plt SYSV ABI we can't make non-local
18764 calls when -fpic/PIC because the plt call stubs use r30. */
18765 if (DEFAULT_ABI == ABI_DARWIN
18766 || (DEFAULT_ABI == ABI_AIX
18768 && !DECL_EXTERNAL (decl)
18769 && (*targetm.binds_local_p) (decl))
18770 || (DEFAULT_ABI == ABI_V4
18771 && (!TARGET_SECURE_PLT
18774 && (*targetm.binds_local_p) (decl)))))
18776 tree attr_list = TYPE_ATTRIBUTES (fntype);
18778 if (!lookup_attribute ("longcall", attr_list)
18779 || lookup_attribute ("shortcall", attr_list))
18786 /* NULL if INSN insn is valid within a low-overhead loop.
18787 Otherwise return why doloop cannot be applied.
18788 PowerPC uses the COUNT register for branch on table instructions. */
18790 static const char *
18791 rs6000_invalid_within_doloop (const_rtx insn)
18794 return "Function call in the loop.";
18797 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18798 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18799 return "Computed branch in the loop.";
18805 rs6000_ra_ever_killed (void)
18811 if (cfun->is_thunk)
18814 if (cfun->machine->lr_save_state)
18815 return cfun->machine->lr_save_state - 1;
18817 /* regs_ever_live has LR marked as used if any sibcalls are present,
18818 but this should not force saving and restoring in the
18819 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18820 clobbers LR, so that is inappropriate. */
18822 /* Also, the prologue can generate a store into LR that
18823 doesn't really count, like this:
18826 bcl to set PIC register
18830 When we're called from the epilogue, we need to avoid counting
18831 this as a store. */
18833 push_topmost_sequence ();
18834 top = get_insns ();
18835 pop_topmost_sequence ();
18836 reg = gen_rtx_REG (Pmode, LR_REGNO);
18838 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18844 if (!SIBLING_CALL_P (insn))
18847 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18849 else if (set_of (reg, insn) != NULL_RTX
18850 && !prologue_epilogue_contains (insn))
18857 /* Emit instructions needed to load the TOC register.
18858 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18859 a constant pool; or for SVR4 -fpic. */
18862 rs6000_emit_load_toc_table (int fromprolog)
18865 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18867 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18870 rtx lab, tmp1, tmp2, got;
18872 lab = gen_label_rtx ();
18873 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18874 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18876 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18878 got = rs6000_got_sym ();
18879 tmp1 = tmp2 = dest;
18882 tmp1 = gen_reg_rtx (Pmode);
18883 tmp2 = gen_reg_rtx (Pmode);
18885 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18886 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18887 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18888 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18890 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18892 emit_insn (gen_load_toc_v4_pic_si ());
18893 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18895 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18898 rtx temp0 = (fromprolog
18899 ? gen_rtx_REG (Pmode, 0)
18900 : gen_reg_rtx (Pmode));
18906 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18907 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18909 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18910 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18912 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18913 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18914 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18920 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18921 lab = gen_label_rtx ();
18922 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18923 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18924 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18926 emit_insn (gen_addsi3 (dest, temp0, dest));
18928 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18930 /* This is for AIX code running in non-PIC ELF32. */
18933 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18934 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18936 emit_insn (gen_elf_high (dest, realsym));
18937 emit_insn (gen_elf_low (dest, dest, realsym));
18941 gcc_assert (DEFAULT_ABI == ABI_AIX);
18944 emit_insn (gen_load_toc_aix_si (dest));
18946 emit_insn (gen_load_toc_aix_di (dest));
18950 /* Emit instructions to restore the link register after determining where
18951 its value has been stored. */
18954 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18956 rs6000_stack_t *info = rs6000_stack_info ();
18959 operands[0] = source;
18960 operands[1] = scratch;
18962 if (info->lr_save_p)
18964 rtx frame_rtx = stack_pointer_rtx;
18965 HOST_WIDE_INT sp_offset = 0;
18968 if (frame_pointer_needed
18969 || cfun->calls_alloca
18970 || info->total_size > 32767)
18972 tmp = gen_frame_mem (Pmode, frame_rtx);
18973 emit_move_insn (operands[1], tmp);
18974 frame_rtx = operands[1];
18976 else if (info->push_p)
18977 sp_offset = info->total_size;
18979 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18980 tmp = gen_frame_mem (Pmode, tmp);
18981 emit_move_insn (tmp, operands[0]);
18984 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18986 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18987 state of lr_save_p so any change from here on would be a bug. In
18988 particular, stop rs6000_ra_ever_killed from considering the SET
18989 of lr we may have added just above. */
18990 cfun->machine->lr_save_state = info->lr_save_p + 1;
18993 static GTY(()) alias_set_type set = -1;
18996 get_TOC_alias_set (void)
18999 set = new_alias_set ();
19003 /* This returns nonzero if the current function uses the TOC. This is
19004 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19005 is generated by the ABI_V4 load_toc_* patterns. */
19012 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19015 rtx pat = PATTERN (insn);
19018 if (GET_CODE (pat) == PARALLEL)
19019 for (i = 0; i < XVECLEN (pat, 0); i++)
19021 rtx sub = XVECEXP (pat, 0, i);
19022 if (GET_CODE (sub) == USE)
19024 sub = XEXP (sub, 0);
19025 if (GET_CODE (sub) == UNSPEC
19026 && XINT (sub, 1) == UNSPEC_TOC)
19036 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19038 rtx tocrel, tocreg;
19040 if (TARGET_DEBUG_ADDR)
19042 if (GET_CODE (symbol) == SYMBOL_REF)
19043 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19047 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19048 GET_RTX_NAME (GET_CODE (symbol)));
19049 debug_rtx (symbol);
19053 if (!can_create_pseudo_p ())
19054 df_set_regs_ever_live (TOC_REGISTER, true);
19056 tocrel = gen_rtx_CONST (Pmode,
19057 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19059 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19060 if (TARGET_CMODEL != CMODEL_SMALL)
19062 rtx hi = gen_rtx_CONST (Pmode,
19063 gen_rtx_PLUS (Pmode, tocreg,
19064 gen_rtx_HIGH (Pmode, tocrel)));
19065 if (largetoc_reg != NULL)
19067 emit_move_insn (largetoc_reg, hi);
19070 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19073 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19076 /* Issue assembly directives that create a reference to the given DWARF
19077 FRAME_TABLE_LABEL from the current function section. */
19079 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19081 fprintf (asm_out_file, "\t.ref %s\n",
19082 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19085 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19086 and the change to the stack pointer. */
19089 rs6000_emit_stack_tie (void)
19091 rtx mem = gen_frame_mem (BLKmode,
19092 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19094 emit_insn (gen_stack_tie (mem));
19097 /* Emit the correct code for allocating stack space, as insns.
19098 If COPY_REG, make sure a copy of the old frame is left there.
19099 The generated code may use hard register 0 as a temporary. */
19102 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19105 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19106 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19107 rtx todec = gen_int_mode (-size, Pmode);
19110 if (INTVAL (todec) != -size)
19112 warning (0, "stack frame too large");
19113 emit_insn (gen_trap ());
19117 if (crtl->limit_stack)
19119 if (REG_P (stack_limit_rtx)
19120 && REGNO (stack_limit_rtx) > 1
19121 && REGNO (stack_limit_rtx) <= 31)
19123 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19124 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19127 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19129 && DEFAULT_ABI == ABI_V4)
19131 rtx toload = gen_rtx_CONST (VOIDmode,
19132 gen_rtx_PLUS (Pmode,
19136 emit_insn (gen_elf_high (tmp_reg, toload));
19137 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19138 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19142 warning (0, "stack limit expression is not supported");
19146 emit_move_insn (copy_reg, stack_reg);
19150 /* Need a note here so that try_split doesn't get confused. */
19151 if (get_last_insn () == NULL_RTX)
19152 emit_note (NOTE_INSN_DELETED);
19153 insn = emit_move_insn (tmp_reg, todec);
19154 try_split (PATTERN (insn), insn, 0);
19158 insn = emit_insn (TARGET_32BIT
19159 ? gen_movsi_update_stack (stack_reg, stack_reg,
19161 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19162 todec, stack_reg));
19163 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19164 it now and set the alias set/attributes. The above gen_*_update
19165 calls will generate a PARALLEL with the MEM set being the first
19167 par = PATTERN (insn);
19168 gcc_assert (GET_CODE (par) == PARALLEL);
19169 set = XVECEXP (par, 0, 0);
19170 gcc_assert (GET_CODE (set) == SET);
19171 mem = SET_DEST (set);
19172 gcc_assert (MEM_P (mem));
19173 MEM_NOTRAP_P (mem) = 1;
19174 set_mem_alias_set (mem, get_frame_alias_set ());
19176 RTX_FRAME_RELATED_P (insn) = 1;
19177 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19178 gen_rtx_SET (VOIDmode, stack_reg,
19179 gen_rtx_PLUS (Pmode, stack_reg,
19180 GEN_INT (-size))));
19183 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19185 #if PROBE_INTERVAL > 32768
19186 #error Cannot use indexed addressing mode for stack probing
19189 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19190 inclusive. These are offsets from the current stack pointer. */
19193 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19195 /* See if we have a constant small number of probes to generate. If so,
19196 that's the easy case. */
19197 if (first + size <= 32768)
19201 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19202 it exceeds SIZE. If only one probe is needed, this will not
19203 generate any code. Then probe at FIRST + SIZE. */
19204 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19205 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19207 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19210 /* Otherwise, do the same as above, but in a loop. Note that we must be
19211 extra careful with variables wrapping around because we might be at
19212 the very top (or the very bottom) of the address space and we have
19213 to be able to handle this case properly; in particular, we use an
19214 equality test for the loop condition. */
19217 HOST_WIDE_INT rounded_size;
19218 rtx r12 = gen_rtx_REG (Pmode, 12);
19219 rtx r0 = gen_rtx_REG (Pmode, 0);
19221 /* Sanity check for the addressing mode we're going to use. */
19222 gcc_assert (first <= 32768);
19224 /* Step 1: round SIZE to the previous multiple of the interval. */
19226 rounded_size = size & -PROBE_INTERVAL;
19229 /* Step 2: compute initial and final value of the loop counter. */
19231 /* TEST_ADDR = SP + FIRST. */
19232 emit_insn (gen_rtx_SET (VOIDmode, r12,
19233 plus_constant (stack_pointer_rtx, -first)));
19235 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19236 if (rounded_size > 32768)
19238 emit_move_insn (r0, GEN_INT (-rounded_size));
19239 emit_insn (gen_rtx_SET (VOIDmode, r0,
19240 gen_rtx_PLUS (Pmode, r12, r0)));
19243 emit_insn (gen_rtx_SET (VOIDmode, r0,
19244 plus_constant (r12, -rounded_size)));
19247 /* Step 3: the loop
19249 while (TEST_ADDR != LAST_ADDR)
19251 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19255 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19256 until it is equal to ROUNDED_SIZE. */
19259 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19261 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19264 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19265 that SIZE is equal to ROUNDED_SIZE. */
19267 if (size != rounded_size)
19268 emit_stack_probe (plus_constant (r12, rounded_size - size));
19272 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19273 absolute addresses. */
19276 output_probe_stack_range (rtx reg1, rtx reg2)
19278 static int labelno = 0;
19279 char loop_lab[32], end_lab[32];
19282 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19283 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19285 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19287 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19291 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19293 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19295 fputs ("\tbeq 0,", asm_out_file);
19296 assemble_name_raw (asm_out_file, end_lab);
19297 fputc ('\n', asm_out_file);
19299 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19300 xops[1] = GEN_INT (-PROBE_INTERVAL);
19301 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19303 /* Probe at TEST_ADDR and branch. */
19304 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19305 fprintf (asm_out_file, "\tb ");
19306 assemble_name_raw (asm_out_file, loop_lab);
19307 fputc ('\n', asm_out_file);
19309 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19314 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19315 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19316 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19317 deduce these equivalences by itself so it wasn't necessary to hold
19318 its hand so much. */
19321 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19322 rtx reg2, rtx rreg)
19326 /* copy_rtx will not make unique copies of registers, so we need to
19327 ensure we don't have unwanted sharing here. */
19329 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19332 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19334 real = copy_rtx (PATTERN (insn));
19336 if (reg2 != NULL_RTX)
19337 real = replace_rtx (real, reg2, rreg);
19339 real = replace_rtx (real, reg,
19340 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19341 STACK_POINTER_REGNUM),
19344 /* We expect that 'real' is either a SET or a PARALLEL containing
19345 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19346 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19348 if (GET_CODE (real) == SET)
19352 temp = simplify_rtx (SET_SRC (set));
19354 SET_SRC (set) = temp;
19355 temp = simplify_rtx (SET_DEST (set));
19357 SET_DEST (set) = temp;
19358 if (GET_CODE (SET_DEST (set)) == MEM)
19360 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19362 XEXP (SET_DEST (set), 0) = temp;
19369 gcc_assert (GET_CODE (real) == PARALLEL);
19370 for (i = 0; i < XVECLEN (real, 0); i++)
19371 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19373 rtx set = XVECEXP (real, 0, i);
19375 temp = simplify_rtx (SET_SRC (set));
19377 SET_SRC (set) = temp;
19378 temp = simplify_rtx (SET_DEST (set));
19380 SET_DEST (set) = temp;
19381 if (GET_CODE (SET_DEST (set)) == MEM)
19383 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19385 XEXP (SET_DEST (set), 0) = temp;
19387 RTX_FRAME_RELATED_P (set) = 1;
19391 RTX_FRAME_RELATED_P (insn) = 1;
19392 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19395 /* Returns an insn that has a vrsave set operation with the
19396 appropriate CLOBBERs. */
19399 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19402 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19403 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19406 = gen_rtx_SET (VOIDmode,
19408 gen_rtx_UNSPEC_VOLATILE (SImode,
19409 gen_rtvec (2, reg, vrsave),
19410 UNSPECV_SET_VRSAVE));
19414 /* We need to clobber the registers in the mask so the scheduler
19415 does not move sets to VRSAVE before sets of AltiVec registers.
19417 However, if the function receives nonlocal gotos, reload will set
19418 all call saved registers live. We will end up with:
19420 (set (reg 999) (mem))
19421 (parallel [ (set (reg vrsave) (unspec blah))
19422 (clobber (reg 999))])
19424 The clobber will cause the store into reg 999 to be dead, and
19425 flow will attempt to delete an epilogue insn. In this case, we
19426 need an unspec use/set of the register. */
19428 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19429 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19431 if (!epiloguep || call_used_regs [i])
19432 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19433 gen_rtx_REG (V4SImode, i));
19436 rtx reg = gen_rtx_REG (V4SImode, i);
19439 = gen_rtx_SET (VOIDmode,
19441 gen_rtx_UNSPEC (V4SImode,
19442 gen_rtvec (1, reg), 27));
19446 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19448 for (i = 0; i < nclobs; ++i)
19449 XVECEXP (insn, 0, i) = clobs[i];
19454 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19455 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19458 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19459 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19461 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19462 rtx replacea, replaceb;
19464 int_rtx = GEN_INT (offset);
19466 /* Some cases that need register indexed addressing. */
19467 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19468 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19469 || (TARGET_E500_DOUBLE && mode == DFmode)
19471 && SPE_VECTOR_MODE (mode)
19472 && !SPE_CONST_OFFSET_OK (offset)))
19474 /* Whomever calls us must make sure r11 is available in the
19475 flow path of instructions in the prologue. */
19476 offset_rtx = gen_rtx_REG (Pmode, 11);
19477 emit_move_insn (offset_rtx, int_rtx);
19479 replacea = offset_rtx;
19480 replaceb = int_rtx;
19484 offset_rtx = int_rtx;
19485 replacea = NULL_RTX;
19486 replaceb = NULL_RTX;
19489 reg = gen_rtx_REG (mode, regno);
19490 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19491 mem = gen_frame_mem (mode, addr);
19493 insn = emit_move_insn (mem, reg);
19495 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19498 /* Emit an offset memory reference suitable for a frame store, while
19499 converting to a valid addressing mode. */
19502 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19504 rtx int_rtx, offset_rtx;
19506 int_rtx = GEN_INT (offset);
19508 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19509 || (TARGET_E500_DOUBLE && mode == DFmode))
19511 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19512 emit_move_insn (offset_rtx, int_rtx);
19515 offset_rtx = int_rtx;
19517 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19520 /* Look for user-defined global regs. We should not save and restore these,
19521 and cannot use stmw/lmw if there are any in its range. */
19524 no_global_regs_above (int first, bool gpr)
19527 int last = gpr ? 32 : 64;
19528 for (i = first; i < last; i++)
19529 if (global_regs[i])
19534 #ifndef TARGET_FIX_AND_CONTINUE
19535 #define TARGET_FIX_AND_CONTINUE 0
19538 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19539 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19540 #define LAST_SAVRES_REGISTER 31
19541 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19543 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19545 /* Temporary holding space for an out-of-line register save/restore
19547 static char savres_routine_name[30];
19549 /* Return the name for an out-of-line register save/restore routine.
19550 We are saving/restoring GPRs if GPR is true. */
19553 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19554 bool savep, bool gpr, bool lr)
19556 const char *prefix = "";
19557 const char *suffix = "";
19559 /* Different targets are supposed to define
19560 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19561 routine name could be defined with:
19563 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19565 This is a nice idea in practice, but in reality, things are
19566 complicated in several ways:
19568 - ELF targets have save/restore routines for GPRs.
19570 - SPE targets use different prefixes for 32/64-bit registers, and
19571 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19573 - PPC64 ELF targets have routines for save/restore of GPRs that
19574 differ in what they do with the link register, so having a set
19575 prefix doesn't work. (We only use one of the save routines at
19576 the moment, though.)
19578 - PPC32 elf targets have "exit" versions of the restore routines
19579 that restore the link register and can save some extra space.
19580 These require an extra suffix. (There are also "tail" versions
19581 of the restore routines and "GOT" versions of the save routines,
19582 but we don't generate those at present. Same problems apply,
19585 We deal with all this by synthesizing our own prefix/suffix and
19586 using that for the simple sprintf call shown above. */
19589 /* No floating point saves on the SPE. */
19593 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19595 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19600 else if (DEFAULT_ABI == ABI_V4)
19606 prefix = savep ? "_savegpr_" : "_restgpr_";
19608 prefix = savep ? "_savefpr_" : "_restfpr_";
19613 else if (DEFAULT_ABI == ABI_AIX)
19615 #ifndef POWERPC_LINUX
19616 /* No out-of-line save/restore routines for GPRs on AIX. */
19617 gcc_assert (!TARGET_AIX || !gpr);
19623 ? (lr ? "_savegpr0_" : "_savegpr1_")
19624 : (lr ? "_restgpr0_" : "_restgpr1_"));
19625 #ifdef POWERPC_LINUX
19627 prefix = (savep ? "_savefpr_" : "_restfpr_");
19631 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19632 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19635 else if (DEFAULT_ABI == ABI_DARWIN)
19636 sorry ("out-of-line save/restore routines not supported on Darwin");
19638 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19640 return savres_routine_name;
19643 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19644 We are saving/restoring GPRs if GPR is true. */
19647 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19650 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19652 int select = ((savep ? 1 : 0) << 2
19654 /* On the SPE, we never have any FPRs, but we do have
19655 32/64-bit versions of the routines. */
19656 ? (info->spe_64bit_regs_used ? 1 : 0)
19657 : (gpr ? 1 : 0)) << 1)
19660 /* Don't generate bogus routine names. */
19661 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19662 && regno <= LAST_SAVRES_REGISTER);
19664 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19670 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19672 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19673 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19674 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19680 /* Emit a sequence of insns, including a stack tie if needed, for
19681 resetting the stack pointer. If SAVRES is true, then don't reset the
19682 stack pointer, but move the base of the frame into r11 for use by
19683 out-of-line register restore routines. */
19686 rs6000_emit_stack_reset (rs6000_stack_t *info,
19687 rtx sp_reg_rtx, rtx frame_reg_rtx,
19688 int sp_offset, bool savres)
19690 /* This blockage is needed so that sched doesn't decide to move
19691 the sp change before the register restores. */
19692 if (frame_reg_rtx != sp_reg_rtx
19694 && info->spe_64bit_regs_used != 0
19695 && info->first_gp_reg_save != 32))
19696 rs6000_emit_stack_tie ();
19698 if (frame_reg_rtx != sp_reg_rtx)
19700 if (sp_offset != 0)
19702 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19703 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19704 GEN_INT (sp_offset)));
19707 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19709 else if (sp_offset != 0)
19711 /* If we are restoring registers out-of-line, we will be using the
19712 "exit" variants of the restore routines, which will reset the
19713 stack for us. But we do need to point r11 into the right place
19714 for those routines. */
19715 rtx dest_reg = (savres
19716 ? gen_rtx_REG (Pmode, 11)
19719 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19720 GEN_INT (sp_offset)));
19727 /* Construct a parallel rtx describing the effect of a call to an
19728 out-of-line register save/restore routine. */
19731 rs6000_make_savres_rtx (rs6000_stack_t *info,
19732 rtx frame_reg_rtx, int save_area_offset,
19733 enum machine_mode reg_mode,
19734 bool savep, bool gpr, bool lr)
19737 int offset, start_reg, end_reg, n_regs;
19738 int reg_size = GET_MODE_SIZE (reg_mode);
19744 ? info->first_gp_reg_save
19745 : info->first_fp_reg_save);
19746 end_reg = gpr ? 32 : 64;
19747 n_regs = end_reg - start_reg;
19748 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19751 RTVEC_ELT (p, offset++) = ret_rtx;
19753 RTVEC_ELT (p, offset++)
19754 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19756 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19757 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19758 RTVEC_ELT (p, offset++)
19759 = gen_rtx_USE (VOIDmode,
19760 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19764 for (i = 0; i < end_reg - start_reg; i++)
19766 rtx addr, reg, mem;
19767 reg = gen_rtx_REG (reg_mode, start_reg + i);
19768 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19769 GEN_INT (save_area_offset + reg_size*i));
19770 mem = gen_frame_mem (reg_mode, addr);
19772 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19774 savep ? reg : mem);
19779 rtx addr, reg, mem;
19780 reg = gen_rtx_REG (Pmode, 0);
19781 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19782 GEN_INT (info->lr_save_offset));
19783 mem = gen_frame_mem (Pmode, addr);
19784 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19787 return gen_rtx_PARALLEL (VOIDmode, p);
19790 /* Determine whether the gp REG is really used. */
19793 rs6000_reg_live_or_pic_offset_p (int reg)
19795 /* If the function calls eh_return, claim used all the registers that would
19796 be checked for liveness otherwise. This is required for the PIC offset
19797 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19798 register allocation purposes in this case. */
19800 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19801 && (!call_used_regs[reg]
19802 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19803 && !TARGET_SINGLE_PIC_BASE
19804 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19805 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19806 && !TARGET_SINGLE_PIC_BASE
19807 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19808 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19811 /* Emit function prologue as insns. */
19814 rs6000_emit_prologue (void)
19816 rs6000_stack_t *info = rs6000_stack_info ();
19817 enum machine_mode reg_mode = Pmode;
19818 int reg_size = TARGET_32BIT ? 4 : 8;
19819 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19820 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19821 rtx frame_reg_rtx = sp_reg_rtx;
19822 rtx cr_save_rtx = NULL_RTX;
19825 int saving_FPRs_inline;
19826 int saving_GPRs_inline;
19827 int using_store_multiple;
19828 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19829 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19830 && call_used_regs[STATIC_CHAIN_REGNUM]);
19831 HOST_WIDE_INT sp_offset = 0;
19833 if (flag_stack_usage_info)
19834 current_function_static_stack_size = info->total_size;
19836 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19837 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19839 if (TARGET_FIX_AND_CONTINUE)
19841 /* gdb on darwin arranges to forward a function from the old
19842 address by modifying the first 5 instructions of the function
19843 to branch to the overriding function. This is necessary to
19844 permit function pointers that point to the old function to
19845 actually forward to the new function. */
19846 emit_insn (gen_nop ());
19847 emit_insn (gen_nop ());
19848 emit_insn (gen_nop ());
19849 emit_insn (gen_nop ());
19850 emit_insn (gen_nop ());
19853 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19855 reg_mode = V2SImode;
19859 strategy = info->savres_strategy;
19860 using_store_multiple = strategy & SAVRES_MULTIPLE;
19861 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19862 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19864 /* For V.4, update stack before we do any saving and set back pointer. */
19865 if (! WORLD_SAVE_P (info)
19867 && (DEFAULT_ABI == ABI_V4
19868 || crtl->calls_eh_return))
19870 bool need_r11 = (TARGET_SPE
19871 ? (!saving_GPRs_inline
19872 && info->spe_64bit_regs_used == 0)
19873 : (!saving_FPRs_inline || !saving_GPRs_inline));
19874 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19876 if (info->total_size < 32767)
19877 sp_offset = info->total_size;
19879 frame_reg_rtx = copy_reg;
19880 else if (info->cr_save_p
19882 || info->first_fp_reg_save < 64
19883 || info->first_gp_reg_save < 32
19884 || info->altivec_size != 0
19885 || info->vrsave_mask != 0
19886 || crtl->calls_eh_return)
19888 copy_reg = frame_ptr_rtx;
19889 frame_reg_rtx = copy_reg;
19893 /* The prologue won't be saving any regs so there is no need
19894 to set up a frame register to access any frame save area.
19895 We also won't be using sp_offset anywhere below, but set
19896 the correct value anyway to protect against future
19897 changes to this function. */
19898 sp_offset = info->total_size;
19900 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19901 if (frame_reg_rtx != sp_reg_rtx)
19902 rs6000_emit_stack_tie ();
19905 /* Handle world saves specially here. */
19906 if (WORLD_SAVE_P (info))
19913 /* save_world expects lr in r0. */
19914 reg0 = gen_rtx_REG (Pmode, 0);
19915 if (info->lr_save_p)
19917 insn = emit_move_insn (reg0,
19918 gen_rtx_REG (Pmode, LR_REGNO));
19919 RTX_FRAME_RELATED_P (insn) = 1;
19922 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19923 assumptions about the offsets of various bits of the stack
19925 gcc_assert (info->gp_save_offset == -220
19926 && info->fp_save_offset == -144
19927 && info->lr_save_offset == 8
19928 && info->cr_save_offset == 4
19931 && (!crtl->calls_eh_return
19932 || info->ehrd_offset == -432)
19933 && info->vrsave_save_offset == -224
19934 && info->altivec_save_offset == -416);
19936 treg = gen_rtx_REG (SImode, 11);
19937 emit_move_insn (treg, GEN_INT (-info->total_size));
19939 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19940 in R11. It also clobbers R12, so beware! */
19942 /* Preserve CR2 for save_world prologues */
19944 sz += 32 - info->first_gp_reg_save;
19945 sz += 64 - info->first_fp_reg_save;
19946 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19947 p = rtvec_alloc (sz);
19949 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19950 gen_rtx_REG (SImode,
19952 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19953 gen_rtx_SYMBOL_REF (Pmode,
19955 /* We do floats first so that the instruction pattern matches
19957 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19959 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19960 ? DFmode : SFmode),
19961 info->first_fp_reg_save + i);
19962 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19963 GEN_INT (info->fp_save_offset
19964 + sp_offset + 8 * i));
19965 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19966 ? DFmode : SFmode), addr);
19968 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19970 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19972 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19973 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19974 GEN_INT (info->altivec_save_offset
19975 + sp_offset + 16 * i));
19976 rtx mem = gen_frame_mem (V4SImode, addr);
19978 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19980 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19982 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19983 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19984 GEN_INT (info->gp_save_offset
19985 + sp_offset + reg_size * i));
19986 rtx mem = gen_frame_mem (reg_mode, addr);
19988 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19992 /* CR register traditionally saved as CR2. */
19993 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19994 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19995 GEN_INT (info->cr_save_offset
19997 rtx mem = gen_frame_mem (reg_mode, addr);
19999 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20001 /* Explain about use of R0. */
20002 if (info->lr_save_p)
20004 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20005 GEN_INT (info->lr_save_offset
20007 rtx mem = gen_frame_mem (reg_mode, addr);
20009 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20011 /* Explain what happens to the stack pointer. */
20013 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20014 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20017 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20018 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20019 treg, GEN_INT (-info->total_size));
20020 sp_offset = info->total_size;
20023 /* If we use the link register, get it into r0. */
20024 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20026 rtx addr, reg, mem;
20028 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20029 gen_rtx_REG (Pmode, LR_REGNO));
20030 RTX_FRAME_RELATED_P (insn) = 1;
20032 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20033 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20035 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20036 GEN_INT (info->lr_save_offset + sp_offset));
20037 reg = gen_rtx_REG (Pmode, 0);
20038 mem = gen_rtx_MEM (Pmode, addr);
20039 /* This should not be of rs6000_sr_alias_set, because of
20040 __builtin_return_address. */
20042 insn = emit_move_insn (mem, reg);
20043 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20044 NULL_RTX, NULL_RTX);
20048 /* If we need to save CR, put it into r12 or r11. */
20049 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20054 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20056 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20057 RTX_FRAME_RELATED_P (insn) = 1;
20058 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20059 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20060 But that's OK. All we have to do is specify that _one_ condition
20061 code register is saved in this stack slot. The thrower's epilogue
20062 will then restore all the call-saved registers.
20063 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20064 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20065 gen_rtx_REG (SImode, CR2_REGNO));
20066 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20069 /* Do any required saving of fpr's. If only one or two to save, do
20070 it ourselves. Otherwise, call function. */
20071 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20074 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20075 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20076 && ! call_used_regs[info->first_fp_reg_save+i]))
20077 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20078 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20080 info->first_fp_reg_save + i,
20081 info->fp_save_offset + sp_offset + 8 * i,
20084 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20088 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20089 info->fp_save_offset + sp_offset,
20091 /*savep=*/true, /*gpr=*/false,
20093 & SAVE_NOINLINE_FPRS_SAVES_LR)
20095 insn = emit_insn (par);
20096 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20097 NULL_RTX, NULL_RTX);
20100 /* Save GPRs. This is done as a PARALLEL if we are using
20101 the store-multiple instructions. */
20102 if (!WORLD_SAVE_P (info)
20104 && info->spe_64bit_regs_used != 0
20105 && info->first_gp_reg_save != 32)
20108 rtx spe_save_area_ptr;
20110 /* Determine whether we can address all of the registers that need
20111 to be saved with an offset from the stack pointer that fits in
20112 the small const field for SPE memory instructions. */
20113 int spe_regs_addressable_via_sp
20114 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20115 + (32 - info->first_gp_reg_save - 1) * reg_size)
20116 && saving_GPRs_inline);
20119 if (spe_regs_addressable_via_sp)
20121 spe_save_area_ptr = frame_reg_rtx;
20122 spe_offset = info->spe_gp_save_offset + sp_offset;
20126 /* Make r11 point to the start of the SPE save area. We need
20127 to be careful here if r11 is holding the static chain. If
20128 it is, then temporarily save it in r0. We would use r0 as
20129 our base register here, but using r0 as a base register in
20130 loads and stores means something different from what we
20132 int ool_adjust = (saving_GPRs_inline
20134 : (info->first_gp_reg_save
20135 - (FIRST_SAVRES_REGISTER+1))*8);
20136 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20137 + sp_offset - ool_adjust);
20139 if (using_static_chain_p)
20141 rtx r0 = gen_rtx_REG (Pmode, 0);
20142 gcc_assert (info->first_gp_reg_save > 11);
20144 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20147 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20148 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20150 GEN_INT (offset)));
20151 /* We need to make sure the move to r11 gets noted for
20152 properly outputting unwind information. */
20153 if (!saving_GPRs_inline)
20154 rs6000_frame_related (insn, frame_reg_rtx, offset,
20155 NULL_RTX, NULL_RTX);
20159 if (saving_GPRs_inline)
20161 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20162 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20164 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20165 rtx offset, addr, mem;
20167 /* We're doing all this to ensure that the offset fits into
20168 the immediate offset of 'evstdd'. */
20169 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20171 offset = GEN_INT (reg_size * i + spe_offset);
20172 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20173 mem = gen_rtx_MEM (V2SImode, addr);
20175 insn = emit_move_insn (mem, reg);
20177 rs6000_frame_related (insn, spe_save_area_ptr,
20178 info->spe_gp_save_offset
20179 + sp_offset + reg_size * i,
20180 offset, const0_rtx);
20187 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20189 /*savep=*/true, /*gpr=*/true,
20191 insn = emit_insn (par);
20192 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20193 NULL_RTX, NULL_RTX);
20197 /* Move the static chain pointer back. */
20198 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20199 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20201 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20205 /* Need to adjust r11 (r12) if we saved any FPRs. */
20206 if (info->first_fp_reg_save != 64)
20208 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20210 rtx offset = GEN_INT (sp_offset
20211 + (-8 * (64-info->first_fp_reg_save)));
20212 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20215 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20216 info->gp_save_offset + sp_offset,
20218 /*savep=*/true, /*gpr=*/true,
20220 & SAVE_NOINLINE_GPRS_SAVES_LR)
20222 insn = emit_insn (par);
20223 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20224 NULL_RTX, NULL_RTX);
20226 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20230 p = rtvec_alloc (32 - info->first_gp_reg_save);
20231 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20233 rtx addr, reg, mem;
20234 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20235 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20236 GEN_INT (info->gp_save_offset
20239 mem = gen_frame_mem (reg_mode, addr);
20241 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20243 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20244 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20245 NULL_RTX, NULL_RTX);
20247 else if (!WORLD_SAVE_P (info))
20250 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20251 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20253 rtx addr, reg, mem;
20254 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20256 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20257 GEN_INT (info->gp_save_offset
20260 mem = gen_frame_mem (reg_mode, addr);
20262 insn = emit_move_insn (mem, reg);
20263 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20264 NULL_RTX, NULL_RTX);
20268 /* ??? There's no need to emit actual instructions here, but it's the
20269 easiest way to get the frame unwind information emitted. */
20270 if (crtl->calls_eh_return)
20272 unsigned int i, regno;
20276 regno = EH_RETURN_DATA_REGNO (i);
20277 if (regno == INVALID_REGNUM)
20280 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20281 info->ehrd_offset + sp_offset
20282 + reg_size * (int) i,
20287 /* In AIX ABI we need to make sure r2 is really saved. */
20288 if (TARGET_AIX && crtl->calls_eh_return)
20290 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20291 long toc_restore_insn;
20293 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20294 || frame_reg_rtx == sp_reg_rtx);
20295 tmp_reg = gen_rtx_REG (Pmode, 11);
20296 tmp_reg_si = gen_rtx_REG (SImode, 11);
20297 if (using_static_chain_p)
20298 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20299 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20300 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20301 /* Peek at instruction to which this function returns. If it's
20302 restoring r2, then we know we've already saved r2. We can't
20303 unconditionally save r2 because the value we have will already
20304 be updated if we arrived at this function via a plt call or
20305 toc adjusting stub. */
20306 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20307 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20308 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20309 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20310 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20311 validate_condition_mode (EQ, CCUNSmode);
20312 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20313 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20314 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20315 toc_save_done = gen_label_rtx ();
20316 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20317 gen_rtx_EQ (VOIDmode, compare_result,
20319 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20321 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20322 JUMP_LABEL (jump) = toc_save_done;
20323 LABEL_NUSES (toc_save_done) += 1;
20325 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, TOC_REGNUM,
20326 sp_offset + 5 * reg_size, info->total_size);
20327 emit_label (toc_save_done);
20328 if (using_static_chain_p)
20329 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20332 /* Save CR if we use any that must be preserved. */
20333 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20335 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20336 GEN_INT (info->cr_save_offset + sp_offset));
20337 rtx mem = gen_frame_mem (SImode, addr);
20338 /* See the large comment above about why CR2_REGNO is used. */
20339 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20341 /* If r12 was used to hold the original sp, copy cr into r0 now
20343 if (REGNO (frame_reg_rtx) == 12)
20347 cr_save_rtx = gen_rtx_REG (SImode, 0);
20348 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20349 RTX_FRAME_RELATED_P (insn) = 1;
20350 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20351 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20353 insn = emit_move_insn (mem, cr_save_rtx);
20355 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20356 NULL_RTX, NULL_RTX);
20359 /* Update stack and set back pointer unless this is V.4,
20360 for which it was done previously. */
20361 if (!WORLD_SAVE_P (info) && info->push_p
20362 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20364 rtx copy_reg = NULL;
20366 if (info->total_size < 32767)
20367 sp_offset = info->total_size;
20368 else if (info->altivec_size != 0
20369 || info->vrsave_mask != 0)
20371 copy_reg = frame_ptr_rtx;
20372 frame_reg_rtx = copy_reg;
20375 sp_offset = info->total_size;
20376 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20377 if (frame_reg_rtx != sp_reg_rtx)
20378 rs6000_emit_stack_tie ();
20381 /* Set frame pointer, if needed. */
20382 if (frame_pointer_needed)
20384 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20386 RTX_FRAME_RELATED_P (insn) = 1;
20389 /* Save AltiVec registers if needed. Save here because the red zone does
20390 not include AltiVec registers. */
20391 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20395 /* There should be a non inline version of this, for when we
20396 are saving lots of vector registers. */
20397 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20398 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20400 rtx areg, savereg, mem;
20403 offset = info->altivec_save_offset + sp_offset
20404 + 16 * (i - info->first_altivec_reg_save);
20406 savereg = gen_rtx_REG (V4SImode, i);
20408 areg = gen_rtx_REG (Pmode, 0);
20409 emit_move_insn (areg, GEN_INT (offset));
20411 /* AltiVec addressing mode is [reg+reg]. */
20412 mem = gen_frame_mem (V4SImode,
20413 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20415 insn = emit_move_insn (mem, savereg);
20417 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20418 areg, GEN_INT (offset));
20422 /* VRSAVE is a bit vector representing which AltiVec registers
20423 are used. The OS uses this to determine which vector
20424 registers to save on a context switch. We need to save
20425 VRSAVE on the stack frame, add whatever AltiVec registers we
20426 used in this function, and do the corresponding magic in the
20429 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20430 && info->vrsave_mask != 0)
20432 rtx reg, mem, vrsave;
20435 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20436 as frame_reg_rtx and r11 as the static chain pointer for
20437 nested functions. */
20438 reg = gen_rtx_REG (SImode, 0);
20439 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20441 emit_insn (gen_get_vrsave_internal (reg));
20443 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20445 if (!WORLD_SAVE_P (info))
20448 offset = info->vrsave_save_offset + sp_offset;
20449 mem = gen_frame_mem (SImode,
20450 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20451 GEN_INT (offset)));
20452 insn = emit_move_insn (mem, reg);
20455 /* Include the registers in the mask. */
20456 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20458 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20461 if (TARGET_SINGLE_PIC_BASE)
20462 return; /* Do not set PIC register */
20464 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20465 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20466 || (DEFAULT_ABI == ABI_V4
20467 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20468 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20470 /* If emit_load_toc_table will use the link register, we need to save
20471 it. We use R12 for this purpose because emit_load_toc_table
20472 can use register 0. This allows us to use a plain 'blr' to return
20473 from the procedure more often. */
20474 int save_LR_around_toc_setup = (TARGET_ELF
20475 && DEFAULT_ABI != ABI_AIX
20477 && ! info->lr_save_p
20478 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20479 if (save_LR_around_toc_setup)
20481 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20483 insn = emit_move_insn (frame_ptr_rtx, lr);
20484 RTX_FRAME_RELATED_P (insn) = 1;
20486 rs6000_emit_load_toc_table (TRUE);
20488 insn = emit_move_insn (lr, frame_ptr_rtx);
20489 RTX_FRAME_RELATED_P (insn) = 1;
20492 rs6000_emit_load_toc_table (TRUE);
20496 if (DEFAULT_ABI == ABI_DARWIN
20497 && flag_pic && crtl->uses_pic_offset_table)
20499 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20500 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20502 /* Save and restore LR locally around this call (in R0). */
20503 if (!info->lr_save_p)
20504 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20506 emit_insn (gen_load_macho_picbase (src));
20508 emit_move_insn (gen_rtx_REG (Pmode,
20509 RS6000_PIC_OFFSET_TABLE_REGNUM),
20512 if (!info->lr_save_p)
20513 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20517 /* If we need to, save the TOC register after doing the stack setup. */
20518 if (rs6000_save_toc_in_prologue_p ())
20519 emit_frame_save (sp_reg_rtx, sp_reg_rtx, reg_mode, TOC_REGNUM,
20520 5 * reg_size, info->total_size);
20523 /* Write function prologue. */
20526 rs6000_output_function_prologue (FILE *file,
20527 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20529 rs6000_stack_t *info = rs6000_stack_info ();
20531 if (TARGET_DEBUG_STACK)
20532 debug_stack_info (info);
20534 /* Write .extern for any function we will call to save and restore
20536 if (info->first_fp_reg_save < 64)
20539 int regno = info->first_fp_reg_save - 32;
20541 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20543 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20544 /*gpr=*/false, /*lr=*/false);
20545 fprintf (file, "\t.extern %s\n", name);
20547 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20549 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20550 /*gpr=*/false, /*lr=*/true);
20551 fprintf (file, "\t.extern %s\n", name);
20555 /* Write .extern for AIX common mode routines, if needed. */
20556 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20558 fputs ("\t.extern __mulh\n", file);
20559 fputs ("\t.extern __mull\n", file);
20560 fputs ("\t.extern __divss\n", file);
20561 fputs ("\t.extern __divus\n", file);
20562 fputs ("\t.extern __quoss\n", file);
20563 fputs ("\t.extern __quous\n", file);
20564 common_mode_defined = 1;
20567 rs6000_pic_labelno++;
20570 /* Non-zero if vmx regs are restored before the frame pop, zero if
20571 we restore after the pop when possible. */
20572 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20574 /* Reload CR from REG. */
20577 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20582 if (using_mfcr_multiple)
20584 for (i = 0; i < 8; i++)
20585 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20587 gcc_assert (count);
20590 if (using_mfcr_multiple && count > 1)
20595 p = rtvec_alloc (count);
20598 for (i = 0; i < 8; i++)
20599 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20601 rtvec r = rtvec_alloc (2);
20602 RTVEC_ELT (r, 0) = reg;
20603 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20604 RTVEC_ELT (p, ndx) =
20605 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20606 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20609 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20610 gcc_assert (ndx == count);
20613 for (i = 0; i < 8; i++)
20614 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20616 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20622 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20623 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20624 below stack pointer not cloberred by signals. */
20627 offset_below_red_zone_p (HOST_WIDE_INT offset)
20629 return offset < (DEFAULT_ABI == ABI_V4
20631 : TARGET_32BIT ? -220 : -288);
20634 /* Emit function epilogue as insns. */
20637 rs6000_emit_epilogue (int sibcall)
20639 rs6000_stack_t *info;
20640 int restoring_GPRs_inline;
20641 int restoring_FPRs_inline;
20642 int using_load_multiple;
20643 int using_mtcr_multiple;
20644 int use_backchain_to_restore_sp;
20648 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20649 rtx frame_reg_rtx = sp_reg_rtx;
20650 rtx cfa_restores = NULL_RTX;
20652 rtx cr_save_reg = NULL_RTX;
20653 enum machine_mode reg_mode = Pmode;
20654 int reg_size = TARGET_32BIT ? 4 : 8;
20657 info = rs6000_stack_info ();
20659 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20661 reg_mode = V2SImode;
20665 strategy = info->savres_strategy;
20666 using_load_multiple = strategy & SAVRES_MULTIPLE;
20667 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20668 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20669 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20670 || rs6000_cpu == PROCESSOR_PPC603
20671 || rs6000_cpu == PROCESSOR_PPC750
20673 /* Restore via the backchain when we have a large frame, since this
20674 is more efficient than an addis, addi pair. The second condition
20675 here will not trigger at the moment; We don't actually need a
20676 frame pointer for alloca, but the generic parts of the compiler
20677 give us one anyway. */
20678 use_backchain_to_restore_sp = (info->total_size > 32767
20679 || info->total_size
20680 + (info->lr_save_p ? info->lr_save_offset : 0)
20682 || (cfun->calls_alloca
20683 && !frame_pointer_needed));
20684 restore_lr = (info->lr_save_p
20685 && (restoring_FPRs_inline
20686 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20687 && (restoring_GPRs_inline
20688 || info->first_fp_reg_save < 64));
20690 if (WORLD_SAVE_P (info))
20694 const char *alloc_rname;
20697 /* eh_rest_world_r10 will return to the location saved in the LR
20698 stack slot (which is not likely to be our caller.)
20699 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20700 rest_world is similar, except any R10 parameter is ignored.
20701 The exception-handling stuff that was here in 2.95 is no
20702 longer necessary. */
20706 + 32 - info->first_gp_reg_save
20707 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20708 + 63 + 1 - info->first_fp_reg_save);
20710 strcpy (rname, ((crtl->calls_eh_return) ?
20711 "*eh_rest_world_r10" : "*rest_world"));
20712 alloc_rname = ggc_strdup (rname);
20715 RTVEC_ELT (p, j++) = ret_rtx;
20716 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20717 gen_rtx_REG (Pmode,
20720 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20721 /* The instruction pattern requires a clobber here;
20722 it is shared with the restVEC helper. */
20724 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20727 /* CR register traditionally saved as CR2. */
20728 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20729 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20730 GEN_INT (info->cr_save_offset));
20731 rtx mem = gen_frame_mem (reg_mode, addr);
20733 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20736 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20738 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20739 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20740 GEN_INT (info->gp_save_offset
20742 rtx mem = gen_frame_mem (reg_mode, addr);
20744 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20746 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20748 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20749 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20750 GEN_INT (info->altivec_save_offset
20752 rtx mem = gen_frame_mem (V4SImode, addr);
20754 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20756 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20758 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20759 ? DFmode : SFmode),
20760 info->first_fp_reg_save + i);
20761 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20762 GEN_INT (info->fp_save_offset
20764 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20765 ? DFmode : SFmode), addr);
20767 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20770 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20772 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20774 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20776 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20778 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20779 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20784 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20786 sp_offset = info->total_size;
20788 /* Restore AltiVec registers if we must do so before adjusting the
20790 if (TARGET_ALTIVEC_ABI
20791 && info->altivec_size != 0
20792 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20793 || (DEFAULT_ABI != ABI_V4
20794 && offset_below_red_zone_p (info->altivec_save_offset))))
20798 if (use_backchain_to_restore_sp)
20800 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20801 emit_move_insn (frame_reg_rtx,
20802 gen_rtx_MEM (Pmode, sp_reg_rtx));
20805 else if (frame_pointer_needed)
20806 frame_reg_rtx = hard_frame_pointer_rtx;
20808 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20809 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20811 rtx addr, areg, mem, reg;
20813 areg = gen_rtx_REG (Pmode, 0);
20815 (areg, GEN_INT (info->altivec_save_offset
20817 + 16 * (i - info->first_altivec_reg_save)));
20819 /* AltiVec addressing mode is [reg+reg]. */
20820 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20821 mem = gen_frame_mem (V4SImode, addr);
20823 reg = gen_rtx_REG (V4SImode, i);
20824 emit_move_insn (reg, mem);
20825 if (offset_below_red_zone_p (info->altivec_save_offset
20826 + (i - info->first_altivec_reg_save)
20828 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20833 /* Restore VRSAVE if we must do so before adjusting the stack. */
20835 && TARGET_ALTIVEC_VRSAVE
20836 && info->vrsave_mask != 0
20837 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20838 || (DEFAULT_ABI != ABI_V4
20839 && offset_below_red_zone_p (info->vrsave_save_offset))))
20841 rtx addr, mem, reg;
20843 if (frame_reg_rtx == sp_reg_rtx)
20845 if (use_backchain_to_restore_sp)
20847 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20848 emit_move_insn (frame_reg_rtx,
20849 gen_rtx_MEM (Pmode, sp_reg_rtx));
20852 else if (frame_pointer_needed)
20853 frame_reg_rtx = hard_frame_pointer_rtx;
20856 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20857 GEN_INT (info->vrsave_save_offset + sp_offset));
20858 mem = gen_frame_mem (SImode, addr);
20859 reg = gen_rtx_REG (SImode, 12);
20860 emit_move_insn (reg, mem);
20862 emit_insn (generate_set_vrsave (reg, info, 1));
20866 /* If we have a large stack frame, restore the old stack pointer
20867 using the backchain. */
20868 if (use_backchain_to_restore_sp)
20870 if (frame_reg_rtx == sp_reg_rtx)
20872 /* Under V.4, don't reset the stack pointer until after we're done
20873 loading the saved registers. */
20874 if (DEFAULT_ABI == ABI_V4)
20875 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20877 insn = emit_move_insn (frame_reg_rtx,
20878 gen_rtx_MEM (Pmode, sp_reg_rtx));
20881 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20882 && DEFAULT_ABI == ABI_V4)
20883 /* frame_reg_rtx has been set up by the altivec restore. */
20887 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20888 frame_reg_rtx = sp_reg_rtx;
20891 /* If we have a frame pointer, we can restore the old stack pointer
20893 else if (frame_pointer_needed)
20895 frame_reg_rtx = sp_reg_rtx;
20896 if (DEFAULT_ABI == ABI_V4)
20897 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20898 /* Prevent reordering memory accesses against stack pointer restore. */
20899 else if (cfun->calls_alloca
20900 || offset_below_red_zone_p (-info->total_size))
20902 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20903 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20904 MEM_NOTRAP_P (mem1) = 1;
20905 MEM_NOTRAP_P (mem2) = 1;
20906 emit_insn (gen_frame_tie (mem1, mem2));
20909 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20910 GEN_INT (info->total_size)));
20913 else if (info->push_p
20914 && DEFAULT_ABI != ABI_V4
20915 && !crtl->calls_eh_return)
20917 /* Prevent reordering memory accesses against stack pointer restore. */
20918 if (cfun->calls_alloca
20919 || offset_below_red_zone_p (-info->total_size))
20921 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20922 MEM_NOTRAP_P (mem) = 1;
20923 emit_insn (gen_stack_tie (mem));
20925 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20926 GEN_INT (info->total_size)));
20929 if (insn && frame_reg_rtx == sp_reg_rtx)
20933 REG_NOTES (insn) = cfa_restores;
20934 cfa_restores = NULL_RTX;
20936 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20937 RTX_FRAME_RELATED_P (insn) = 1;
20940 /* Restore AltiVec registers if we have not done so already. */
20941 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20942 && TARGET_ALTIVEC_ABI
20943 && info->altivec_size != 0
20944 && (DEFAULT_ABI == ABI_V4
20945 || !offset_below_red_zone_p (info->altivec_save_offset)))
20949 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20950 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20952 rtx addr, areg, mem, reg;
20954 areg = gen_rtx_REG (Pmode, 0);
20956 (areg, GEN_INT (info->altivec_save_offset
20958 + 16 * (i - info->first_altivec_reg_save)));
20960 /* AltiVec addressing mode is [reg+reg]. */
20961 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20962 mem = gen_frame_mem (V4SImode, addr);
20964 reg = gen_rtx_REG (V4SImode, i);
20965 emit_move_insn (reg, mem);
20966 if (DEFAULT_ABI == ABI_V4)
20967 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20972 /* Restore VRSAVE if we have not done so already. */
20973 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20975 && TARGET_ALTIVEC_VRSAVE
20976 && info->vrsave_mask != 0
20977 && (DEFAULT_ABI == ABI_V4
20978 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20980 rtx addr, mem, reg;
20982 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20983 GEN_INT (info->vrsave_save_offset + sp_offset));
20984 mem = gen_frame_mem (SImode, addr);
20985 reg = gen_rtx_REG (SImode, 12);
20986 emit_move_insn (reg, mem);
20988 emit_insn (generate_set_vrsave (reg, info, 1));
20991 /* Get the old lr if we saved it. If we are restoring registers
20992 out-of-line, then the out-of-line routines can do this for us. */
20993 if (restore_lr && restoring_GPRs_inline)
20995 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20996 info->lr_save_offset + sp_offset);
20998 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21001 /* Get the old cr if we saved it. */
21002 if (info->cr_save_p)
21004 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21005 GEN_INT (info->cr_save_offset + sp_offset));
21006 rtx mem = gen_frame_mem (SImode, addr);
21008 cr_save_reg = gen_rtx_REG (SImode,
21009 DEFAULT_ABI == ABI_AIX
21010 && !restoring_GPRs_inline
21011 && info->first_fp_reg_save < 64
21013 emit_move_insn (cr_save_reg, mem);
21016 /* Set LR here to try to overlap restores below. LR is always saved
21017 above incoming stack, so it never needs REG_CFA_RESTORE. */
21018 if (restore_lr && restoring_GPRs_inline)
21019 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21020 gen_rtx_REG (Pmode, 0));
21022 /* Load exception handler data registers, if needed. */
21023 if (crtl->calls_eh_return)
21025 unsigned int i, regno;
21029 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21030 GEN_INT (sp_offset + 5 * reg_size));
21031 rtx mem = gen_frame_mem (reg_mode, addr);
21033 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21040 regno = EH_RETURN_DATA_REGNO (i);
21041 if (regno == INVALID_REGNUM)
21044 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21045 info->ehrd_offset + sp_offset
21046 + reg_size * (int) i);
21048 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21052 /* Restore GPRs. This is done as a PARALLEL if we are using
21053 the load-multiple instructions. */
21055 && info->spe_64bit_regs_used != 0
21056 && info->first_gp_reg_save != 32)
21058 /* Determine whether we can address all of the registers that need
21059 to be saved with an offset from the stack pointer that fits in
21060 the small const field for SPE memory instructions. */
21061 int spe_regs_addressable_via_sp
21062 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21063 + (32 - info->first_gp_reg_save - 1) * reg_size)
21064 && restoring_GPRs_inline);
21067 if (spe_regs_addressable_via_sp)
21068 spe_offset = info->spe_gp_save_offset + sp_offset;
21071 rtx old_frame_reg_rtx = frame_reg_rtx;
21072 /* Make r11 point to the start of the SPE save area. We worried about
21073 not clobbering it when we were saving registers in the prologue.
21074 There's no need to worry here because the static chain is passed
21075 anew to every function. */
21076 int ool_adjust = (restoring_GPRs_inline
21078 : (info->first_gp_reg_save
21079 - (FIRST_SAVRES_REGISTER+1))*8);
21081 if (frame_reg_rtx == sp_reg_rtx)
21082 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21083 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21084 GEN_INT (info->spe_gp_save_offset
21087 /* Keep the invariant that frame_reg_rtx + sp_offset points
21088 at the top of the stack frame. */
21089 sp_offset = -info->spe_gp_save_offset;
21094 if (restoring_GPRs_inline)
21096 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21097 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21099 rtx offset, addr, mem, reg;
21101 /* We're doing all this to ensure that the immediate offset
21102 fits into the immediate field of 'evldd'. */
21103 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21105 offset = GEN_INT (spe_offset + reg_size * i);
21106 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21107 mem = gen_rtx_MEM (V2SImode, addr);
21108 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21110 insn = emit_move_insn (reg, mem);
21111 if (DEFAULT_ABI == ABI_V4)
21113 if (frame_pointer_needed
21114 && info->first_gp_reg_save + i
21115 == HARD_FRAME_POINTER_REGNUM)
21117 add_reg_note (insn, REG_CFA_DEF_CFA,
21118 plus_constant (frame_reg_rtx,
21120 RTX_FRAME_RELATED_P (insn) = 1;
21123 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21132 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21134 /*savep=*/false, /*gpr=*/true,
21136 emit_jump_insn (par);
21137 /* We don't want anybody else emitting things after we jumped
21142 else if (!restoring_GPRs_inline)
21144 /* We are jumping to an out-of-line function. */
21145 bool can_use_exit = info->first_fp_reg_save == 64;
21148 /* Emit stack reset code if we need it. */
21150 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21151 sp_offset, can_use_exit);
21154 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21157 GEN_INT (sp_offset - info->fp_size)));
21158 if (REGNO (frame_reg_rtx) == 11)
21159 sp_offset += info->fp_size;
21162 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21163 info->gp_save_offset, reg_mode,
21164 /*savep=*/false, /*gpr=*/true,
21165 /*lr=*/can_use_exit);
21169 if (info->cr_save_p)
21171 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21172 if (DEFAULT_ABI == ABI_V4)
21174 = alloc_reg_note (REG_CFA_RESTORE,
21175 gen_rtx_REG (SImode, CR2_REGNO),
21179 emit_jump_insn (par);
21181 /* We don't want anybody else emitting things after we jumped
21186 insn = emit_insn (par);
21187 if (DEFAULT_ABI == ABI_V4)
21189 if (frame_pointer_needed)
21191 add_reg_note (insn, REG_CFA_DEF_CFA,
21192 plus_constant (frame_reg_rtx, sp_offset));
21193 RTX_FRAME_RELATED_P (insn) = 1;
21196 for (i = info->first_gp_reg_save; i < 32; i++)
21198 = alloc_reg_note (REG_CFA_RESTORE,
21199 gen_rtx_REG (reg_mode, i), cfa_restores);
21202 else if (using_load_multiple)
21205 p = rtvec_alloc (32 - info->first_gp_reg_save);
21206 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21208 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21209 GEN_INT (info->gp_save_offset
21212 rtx mem = gen_frame_mem (reg_mode, addr);
21213 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21215 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21216 if (DEFAULT_ABI == ABI_V4)
21217 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21220 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21221 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21223 add_reg_note (insn, REG_CFA_DEF_CFA,
21224 plus_constant (frame_reg_rtx, sp_offset));
21225 RTX_FRAME_RELATED_P (insn) = 1;
21230 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21231 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21233 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21234 GEN_INT (info->gp_save_offset
21237 rtx mem = gen_frame_mem (reg_mode, addr);
21238 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21240 insn = emit_move_insn (reg, mem);
21241 if (DEFAULT_ABI == ABI_V4)
21243 if (frame_pointer_needed
21244 && info->first_gp_reg_save + i
21245 == HARD_FRAME_POINTER_REGNUM)
21247 add_reg_note (insn, REG_CFA_DEF_CFA,
21248 plus_constant (frame_reg_rtx, sp_offset));
21249 RTX_FRAME_RELATED_P (insn) = 1;
21252 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21258 if (restore_lr && !restoring_GPRs_inline)
21260 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21261 info->lr_save_offset + sp_offset);
21263 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21264 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21265 gen_rtx_REG (Pmode, 0));
21268 /* Restore fpr's if we need to do it without calling a function. */
21269 if (restoring_FPRs_inline)
21270 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21271 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21272 && ! call_used_regs[info->first_fp_reg_save+i]))
21274 rtx addr, mem, reg;
21275 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21276 GEN_INT (info->fp_save_offset
21279 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21280 ? DFmode : SFmode), addr);
21281 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21282 ? DFmode : SFmode),
21283 info->first_fp_reg_save + i);
21285 emit_move_insn (reg, mem);
21286 if (DEFAULT_ABI == ABI_V4)
21287 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21291 /* If we saved cr, restore it here. Just those that were used. */
21292 if (info->cr_save_p)
21294 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21295 if (DEFAULT_ABI == ABI_V4)
21297 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21301 /* If this is V.4, unwind the stack pointer after all of the loads
21303 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21304 sp_offset, !restoring_FPRs_inline);
21309 REG_NOTES (insn) = cfa_restores;
21310 cfa_restores = NULL_RTX;
21312 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21313 RTX_FRAME_RELATED_P (insn) = 1;
21316 if (crtl->calls_eh_return)
21318 rtx sa = EH_RETURN_STACKADJ_RTX;
21319 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21325 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21326 if (! restoring_FPRs_inline)
21327 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21329 p = rtvec_alloc (2);
21331 RTVEC_ELT (p, 0) = ret_rtx;
21332 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21333 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21334 : gen_rtx_CLOBBER (VOIDmode,
21335 gen_rtx_REG (Pmode, 65)));
21337 /* If we have to restore more than two FP registers, branch to the
21338 restore function. It will return to our caller. */
21339 if (! restoring_FPRs_inline)
21344 sym = rs6000_savres_routine_sym (info,
21348 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21349 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21350 gen_rtx_REG (Pmode,
21351 DEFAULT_ABI == ABI_AIX
21353 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21356 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21357 GEN_INT (info->fp_save_offset + 8*i));
21358 mem = gen_frame_mem (DFmode, addr);
21360 RTVEC_ELT (p, i+4) =
21361 gen_rtx_SET (VOIDmode,
21362 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21367 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21371 /* Write function epilogue. */
21374 rs6000_output_function_epilogue (FILE *file,
21375 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21378 macho_branch_islands ();
21379 /* Mach-O doesn't support labels at the end of objects, so if
21380 it looks like we might want one, insert a NOP. */
21382 rtx insn = get_last_insn ();
21385 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21386 insn = PREV_INSN (insn);
21390 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21391 fputs ("\tnop\n", file);
21395 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21398 We don't output a traceback table if -finhibit-size-directive was
21399 used. The documentation for -finhibit-size-directive reads
21400 ``don't output a @code{.size} assembler directive, or anything
21401 else that would cause trouble if the function is split in the
21402 middle, and the two halves are placed at locations far apart in
21403 memory.'' The traceback table has this property, since it
21404 includes the offset from the start of the function to the
21405 traceback table itself.
21407 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21408 different traceback table. */
21409 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21410 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21412 const char *fname = NULL;
21413 const char *language_string = lang_hooks.name;
21414 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21416 int optional_tbtab;
21417 rs6000_stack_t *info = rs6000_stack_info ();
21419 if (rs6000_traceback == traceback_full)
21420 optional_tbtab = 1;
21421 else if (rs6000_traceback == traceback_part)
21422 optional_tbtab = 0;
21424 optional_tbtab = !optimize_size && !TARGET_ELF;
21426 if (optional_tbtab)
21428 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21429 while (*fname == '.') /* V.4 encodes . in the name */
21432 /* Need label immediately before tbtab, so we can compute
21433 its offset from the function start. */
21434 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21435 ASM_OUTPUT_LABEL (file, fname);
21438 /* The .tbtab pseudo-op can only be used for the first eight
21439 expressions, since it can't handle the possibly variable
21440 length fields that follow. However, if you omit the optional
21441 fields, the assembler outputs zeros for all optional fields
21442 anyways, giving each variable length field is minimum length
21443 (as defined in sys/debug.h). Thus we can not use the .tbtab
21444 pseudo-op at all. */
21446 /* An all-zero word flags the start of the tbtab, for debuggers
21447 that have to find it by searching forward from the entry
21448 point or from the current pc. */
21449 fputs ("\t.long 0\n", file);
21451 /* Tbtab format type. Use format type 0. */
21452 fputs ("\t.byte 0,", file);
21454 /* Language type. Unfortunately, there does not seem to be any
21455 official way to discover the language being compiled, so we
21456 use language_string.
21457 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21458 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21459 a number, so for now use 9. LTO and Go aren't assigned numbers
21460 either, so for now use 0. */
21461 if (! strcmp (language_string, "GNU C")
21462 || ! strcmp (language_string, "GNU GIMPLE")
21463 || ! strcmp (language_string, "GNU Go"))
21465 else if (! strcmp (language_string, "GNU F77")
21466 || ! strcmp (language_string, "GNU Fortran"))
21468 else if (! strcmp (language_string, "GNU Pascal"))
21470 else if (! strcmp (language_string, "GNU Ada"))
21472 else if (! strcmp (language_string, "GNU C++")
21473 || ! strcmp (language_string, "GNU Objective-C++"))
21475 else if (! strcmp (language_string, "GNU Java"))
21477 else if (! strcmp (language_string, "GNU Objective-C"))
21480 gcc_unreachable ();
21481 fprintf (file, "%d,", i);
21483 /* 8 single bit fields: global linkage (not set for C extern linkage,
21484 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21485 from start of procedure stored in tbtab, internal function, function
21486 has controlled storage, function has no toc, function uses fp,
21487 function logs/aborts fp operations. */
21488 /* Assume that fp operations are used if any fp reg must be saved. */
21489 fprintf (file, "%d,",
21490 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21492 /* 6 bitfields: function is interrupt handler, name present in
21493 proc table, function calls alloca, on condition directives
21494 (controls stack walks, 3 bits), saves condition reg, saves
21496 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21497 set up as a frame pointer, even when there is no alloca call. */
21498 fprintf (file, "%d,",
21499 ((optional_tbtab << 6)
21500 | ((optional_tbtab & frame_pointer_needed) << 5)
21501 | (info->cr_save_p << 1)
21502 | (info->lr_save_p)));
21504 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21506 fprintf (file, "%d,",
21507 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21509 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21510 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21512 if (optional_tbtab)
21514 /* Compute the parameter info from the function decl argument
21517 int next_parm_info_bit = 31;
21519 for (decl = DECL_ARGUMENTS (current_function_decl);
21520 decl; decl = DECL_CHAIN (decl))
21522 rtx parameter = DECL_INCOMING_RTL (decl);
21523 enum machine_mode mode = GET_MODE (parameter);
21525 if (GET_CODE (parameter) == REG)
21527 if (SCALAR_FLOAT_MODE_P (mode))
21548 gcc_unreachable ();
21551 /* If only one bit will fit, don't or in this entry. */
21552 if (next_parm_info_bit > 0)
21553 parm_info |= (bits << (next_parm_info_bit - 1));
21554 next_parm_info_bit -= 2;
21558 fixed_parms += ((GET_MODE_SIZE (mode)
21559 + (UNITS_PER_WORD - 1))
21561 next_parm_info_bit -= 1;
21567 /* Number of fixed point parameters. */
21568 /* This is actually the number of words of fixed point parameters; thus
21569 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21570 fprintf (file, "%d,", fixed_parms);
21572 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21574 /* This is actually the number of fp registers that hold parameters;
21575 and thus the maximum value is 13. */
21576 /* Set parameters on stack bit if parameters are not in their original
21577 registers, regardless of whether they are on the stack? Xlc
21578 seems to set the bit when not optimizing. */
21579 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21581 if (! optional_tbtab)
21584 /* Optional fields follow. Some are variable length. */
21586 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21587 11 double float. */
21588 /* There is an entry for each parameter in a register, in the order that
21589 they occur in the parameter list. Any intervening arguments on the
21590 stack are ignored. If the list overflows a long (max possible length
21591 34 bits) then completely leave off all elements that don't fit. */
21592 /* Only emit this long if there was at least one parameter. */
21593 if (fixed_parms || float_parms)
21594 fprintf (file, "\t.long %d\n", parm_info);
21596 /* Offset from start of code to tb table. */
21597 fputs ("\t.long ", file);
21598 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21599 RS6000_OUTPUT_BASENAME (file, fname);
21601 rs6000_output_function_entry (file, fname);
21604 /* Interrupt handler mask. */
21605 /* Omit this long, since we never set the interrupt handler bit
21608 /* Number of CTL (controlled storage) anchors. */
21609 /* Omit this long, since the has_ctl bit is never set above. */
21611 /* Displacement into stack of each CTL anchor. */
21612 /* Omit this list of longs, because there are no CTL anchors. */
21614 /* Length of function name. */
21617 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21619 /* Function name. */
21620 assemble_string (fname, strlen (fname));
21622 /* Register for alloca automatic storage; this is always reg 31.
21623 Only emit this if the alloca bit was set above. */
21624 if (frame_pointer_needed)
21625 fputs ("\t.byte 31\n", file);
21627 fputs ("\t.align 2\n", file);
21631 /* A C compound statement that outputs the assembler code for a thunk
21632 function, used to implement C++ virtual function calls with
21633 multiple inheritance. The thunk acts as a wrapper around a virtual
21634 function, adjusting the implicit object parameter before handing
21635 control off to the real function.
21637 First, emit code to add the integer DELTA to the location that
21638 contains the incoming first argument. Assume that this argument
21639 contains a pointer, and is the one used to pass the `this' pointer
21640 in C++. This is the incoming argument *before* the function
21641 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21642 values of all other incoming arguments.
21644 After the addition, emit code to jump to FUNCTION, which is a
21645 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21646 not touch the return address. Hence returning from FUNCTION will
21647 return to whoever called the current `thunk'.
21649 The effect must be as if FUNCTION had been called directly with the
21650 adjusted first argument. This macro is responsible for emitting
21651 all of the code for a thunk function; output_function_prologue()
21652 and output_function_epilogue() are not invoked.
21654 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21655 been extracted from it.) It might possibly be useful on some
21656 targets, but probably not.
21658 If you do not define this macro, the target-independent code in the
21659 C++ frontend will generate a less efficient heavyweight thunk that
21660 calls FUNCTION instead of jumping to it. The generic approach does
21661 not support varargs. */
21664 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21665 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21668 rtx this_rtx, insn, funexp;
21670 reload_completed = 1;
21671 epilogue_completed = 1;
21673 /* Mark the end of the (empty) prologue. */
21674 emit_note (NOTE_INSN_PROLOGUE_END);
21676 /* Find the "this" pointer. If the function returns a structure,
21677 the structure return pointer is in r3. */
21678 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21679 this_rtx = gen_rtx_REG (Pmode, 4);
21681 this_rtx = gen_rtx_REG (Pmode, 3);
21683 /* Apply the constant offset, if required. */
21685 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21687 /* Apply the offset from the vtable, if required. */
21690 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21691 rtx tmp = gen_rtx_REG (Pmode, 12);
21693 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21694 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21696 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21697 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21701 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21703 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21705 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21708 /* Generate a tail call to the target function. */
21709 if (!TREE_USED (function))
21711 assemble_external (function);
21712 TREE_USED (function) = 1;
21714 funexp = XEXP (DECL_RTL (function), 0);
21715 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21718 if (MACHOPIC_INDIRECT)
21719 funexp = machopic_indirect_call_target (funexp);
21722 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21723 generate sibcall RTL explicitly. */
21724 insn = emit_call_insn (
21725 gen_rtx_PARALLEL (VOIDmode,
21727 gen_rtx_CALL (VOIDmode,
21728 funexp, const0_rtx),
21729 gen_rtx_USE (VOIDmode, const0_rtx),
21730 gen_rtx_USE (VOIDmode,
21731 gen_rtx_REG (SImode,
21734 SIBLING_CALL_P (insn) = 1;
21737 /* Run just enough of rest_of_compilation to get the insns emitted.
21738 There's not really enough bulk here to make other passes such as
21739 instruction scheduling worth while. Note that use_thunk calls
21740 assemble_start_function and assemble_end_function. */
21741 insn = get_insns ();
21742 insn_locators_alloc ();
21743 shorten_branches (insn);
21744 final_start_function (insn, file, 1);
21745 final (insn, file, 1);
21746 final_end_function ();
21748 reload_completed = 0;
21749 epilogue_completed = 0;
21752 /* A quick summary of the various types of 'constant-pool tables'
21755 Target Flags Name One table per
21756 AIX (none) AIX TOC object file
21757 AIX -mfull-toc AIX TOC object file
21758 AIX -mminimal-toc AIX minimal TOC translation unit
21759 SVR4/EABI (none) SVR4 SDATA object file
21760 SVR4/EABI -fpic SVR4 pic object file
21761 SVR4/EABI -fPIC SVR4 PIC translation unit
21762 SVR4/EABI -mrelocatable EABI TOC function
21763 SVR4/EABI -maix AIX TOC object file
21764 SVR4/EABI -maix -mminimal-toc
21765 AIX minimal TOC translation unit
21767 Name Reg. Set by entries contains:
21768 made by addrs? fp? sum?
21770 AIX TOC 2 crt0 as Y option option
21771 AIX minimal TOC 30 prolog gcc Y Y option
21772 SVR4 SDATA 13 crt0 gcc N Y N
21773 SVR4 pic 30 prolog ld Y not yet N
21774 SVR4 PIC 30 prolog gcc Y option option
21775 EABI TOC 30 prolog gcc Y option option
21779 /* Hash functions for the hash table. */
21782 rs6000_hash_constant (rtx k)
21784 enum rtx_code code = GET_CODE (k);
21785 enum machine_mode mode = GET_MODE (k);
21786 unsigned result = (code << 3) ^ mode;
21787 const char *format;
21790 format = GET_RTX_FORMAT (code);
21791 flen = strlen (format);
21797 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21800 if (mode != VOIDmode)
21801 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21813 for (; fidx < flen; fidx++)
21814 switch (format[fidx])
21819 const char *str = XSTR (k, fidx);
21820 len = strlen (str);
21821 result = result * 613 + len;
21822 for (i = 0; i < len; i++)
21823 result = result * 613 + (unsigned) str[i];
21828 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21832 result = result * 613 + (unsigned) XINT (k, fidx);
21835 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21836 result = result * 613 + (unsigned) XWINT (k, fidx);
21840 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21841 result = result * 613 + (unsigned) (XWINT (k, fidx)
21848 gcc_unreachable ();
21855 toc_hash_function (const void *hash_entry)
21857 const struct toc_hash_struct *thc =
21858 (const struct toc_hash_struct *) hash_entry;
21859 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21862 /* Compare H1 and H2 for equivalence. */
21865 toc_hash_eq (const void *h1, const void *h2)
21867 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21868 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21870 if (((const struct toc_hash_struct *) h1)->key_mode
21871 != ((const struct toc_hash_struct *) h2)->key_mode)
21874 return rtx_equal_p (r1, r2);
21877 /* These are the names given by the C++ front-end to vtables, and
21878 vtable-like objects. Ideally, this logic should not be here;
21879 instead, there should be some programmatic way of inquiring as
21880 to whether or not an object is a vtable. */
21882 #define VTABLE_NAME_P(NAME) \
21883 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21884 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21885 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21886 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21887 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21889 #ifdef NO_DOLLAR_IN_LABEL
21890 /* Return a GGC-allocated character string translating dollar signs in
21891 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21894 rs6000_xcoff_strip_dollar (const char *name)
21900 q = (const char *) strchr (name, '$');
21902 if (q == 0 || q == name)
21905 len = strlen (name);
21906 strip = XALLOCAVEC (char, len + 1);
21907 strcpy (strip, name);
21908 p = strip + (q - name);
21912 p = strchr (p + 1, '$');
21915 return ggc_alloc_string (strip, len);
21920 rs6000_output_symbol_ref (FILE *file, rtx x)
21922 /* Currently C++ toc references to vtables can be emitted before it
21923 is decided whether the vtable is public or private. If this is
21924 the case, then the linker will eventually complain that there is
21925 a reference to an unknown section. Thus, for vtables only,
21926 we emit the TOC reference to reference the symbol and not the
21928 const char *name = XSTR (x, 0);
21930 if (VTABLE_NAME_P (name))
21932 RS6000_OUTPUT_BASENAME (file, name);
21935 assemble_name (file, name);
21938 /* Output a TOC entry. We derive the entry name from what is being
21942 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21945 const char *name = buf;
21947 HOST_WIDE_INT offset = 0;
21949 gcc_assert (!TARGET_NO_TOC);
21951 /* When the linker won't eliminate them, don't output duplicate
21952 TOC entries (this happens on AIX if there is any kind of TOC,
21953 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21955 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21957 struct toc_hash_struct *h;
21960 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
21961 time because GGC is not initialized at that point. */
21962 if (toc_hash_table == NULL)
21963 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21964 toc_hash_eq, NULL);
21966 h = ggc_alloc_toc_hash_struct ();
21968 h->key_mode = mode;
21969 h->labelno = labelno;
21971 found = htab_find_slot (toc_hash_table, h, INSERT);
21972 if (*found == NULL)
21974 else /* This is indeed a duplicate.
21975 Set this label equal to that label. */
21977 fputs ("\t.set ", file);
21978 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21979 fprintf (file, "%d,", labelno);
21980 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21981 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21987 /* If we're going to put a double constant in the TOC, make sure it's
21988 aligned properly when strict alignment is on. */
21989 if (GET_CODE (x) == CONST_DOUBLE
21990 && STRICT_ALIGNMENT
21991 && GET_MODE_BITSIZE (mode) >= 64
21992 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21993 ASM_OUTPUT_ALIGN (file, 3);
21996 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21998 /* Handle FP constants specially. Note that if we have a minimal
21999 TOC, things we put here aren't actually in the TOC, so we can allow
22001 if (GET_CODE (x) == CONST_DOUBLE &&
22002 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22004 REAL_VALUE_TYPE rv;
22007 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22008 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22009 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22011 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22015 if (TARGET_MINIMAL_TOC)
22016 fputs (DOUBLE_INT_ASM_OP, file);
22018 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22019 k[0] & 0xffffffff, k[1] & 0xffffffff,
22020 k[2] & 0xffffffff, k[3] & 0xffffffff);
22021 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22022 k[0] & 0xffffffff, k[1] & 0xffffffff,
22023 k[2] & 0xffffffff, k[3] & 0xffffffff);
22028 if (TARGET_MINIMAL_TOC)
22029 fputs ("\t.long ", file);
22031 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22032 k[0] & 0xffffffff, k[1] & 0xffffffff,
22033 k[2] & 0xffffffff, k[3] & 0xffffffff);
22034 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22035 k[0] & 0xffffffff, k[1] & 0xffffffff,
22036 k[2] & 0xffffffff, k[3] & 0xffffffff);
22040 else if (GET_CODE (x) == CONST_DOUBLE &&
22041 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22043 REAL_VALUE_TYPE rv;
22046 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22048 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22049 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22051 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22055 if (TARGET_MINIMAL_TOC)
22056 fputs (DOUBLE_INT_ASM_OP, file);
22058 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22059 k[0] & 0xffffffff, k[1] & 0xffffffff);
22060 fprintf (file, "0x%lx%08lx\n",
22061 k[0] & 0xffffffff, k[1] & 0xffffffff);
22066 if (TARGET_MINIMAL_TOC)
22067 fputs ("\t.long ", file);
22069 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22070 k[0] & 0xffffffff, k[1] & 0xffffffff);
22071 fprintf (file, "0x%lx,0x%lx\n",
22072 k[0] & 0xffffffff, k[1] & 0xffffffff);
22076 else if (GET_CODE (x) == CONST_DOUBLE &&
22077 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22079 REAL_VALUE_TYPE rv;
22082 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22083 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22084 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22086 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22090 if (TARGET_MINIMAL_TOC)
22091 fputs (DOUBLE_INT_ASM_OP, file);
22093 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22094 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22099 if (TARGET_MINIMAL_TOC)
22100 fputs ("\t.long ", file);
22102 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22103 fprintf (file, "0x%lx\n", l & 0xffffffff);
22107 else if (GET_MODE (x) == VOIDmode
22108 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22110 unsigned HOST_WIDE_INT low;
22111 HOST_WIDE_INT high;
22113 if (GET_CODE (x) == CONST_DOUBLE)
22115 low = CONST_DOUBLE_LOW (x);
22116 high = CONST_DOUBLE_HIGH (x);
22119 #if HOST_BITS_PER_WIDE_INT == 32
22122 high = (low & 0x80000000) ? ~0 : 0;
22126 low = INTVAL (x) & 0xffffffff;
22127 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22131 /* TOC entries are always Pmode-sized, but since this
22132 is a bigendian machine then if we're putting smaller
22133 integer constants in the TOC we have to pad them.
22134 (This is still a win over putting the constants in
22135 a separate constant pool, because then we'd have
22136 to have both a TOC entry _and_ the actual constant.)
22138 For a 32-bit target, CONST_INT values are loaded and shifted
22139 entirely within `low' and can be stored in one TOC entry. */
22141 /* It would be easy to make this work, but it doesn't now. */
22142 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22144 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22146 #if HOST_BITS_PER_WIDE_INT == 32
22147 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22148 POINTER_SIZE, &low, &high, 0);
22151 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22152 high = (HOST_WIDE_INT) low >> 32;
22159 if (TARGET_MINIMAL_TOC)
22160 fputs (DOUBLE_INT_ASM_OP, file);
22162 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22163 (long) high & 0xffffffff, (long) low & 0xffffffff);
22164 fprintf (file, "0x%lx%08lx\n",
22165 (long) high & 0xffffffff, (long) low & 0xffffffff);
22170 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22172 if (TARGET_MINIMAL_TOC)
22173 fputs ("\t.long ", file);
22175 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22176 (long) high & 0xffffffff, (long) low & 0xffffffff);
22177 fprintf (file, "0x%lx,0x%lx\n",
22178 (long) high & 0xffffffff, (long) low & 0xffffffff);
22182 if (TARGET_MINIMAL_TOC)
22183 fputs ("\t.long ", file);
22185 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22186 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22192 if (GET_CODE (x) == CONST)
22194 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22195 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22197 base = XEXP (XEXP (x, 0), 0);
22198 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22201 switch (GET_CODE (base))
22204 name = XSTR (base, 0);
22208 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22209 CODE_LABEL_NUMBER (XEXP (base, 0)));
22213 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22217 gcc_unreachable ();
22220 if (TARGET_MINIMAL_TOC)
22221 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22224 fputs ("\t.tc ", file);
22225 RS6000_OUTPUT_BASENAME (file, name);
22228 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22230 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22232 fputs ("[TC],", file);
22235 /* Currently C++ toc references to vtables can be emitted before it
22236 is decided whether the vtable is public or private. If this is
22237 the case, then the linker will eventually complain that there is
22238 a TOC reference to an unknown section. Thus, for vtables only,
22239 we emit the TOC reference to reference the symbol and not the
22241 if (VTABLE_NAME_P (name))
22243 RS6000_OUTPUT_BASENAME (file, name);
22245 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22246 else if (offset > 0)
22247 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22250 output_addr_const (file, x);
22254 /* Output an assembler pseudo-op to write an ASCII string of N characters
22255 starting at P to FILE.
22257 On the RS/6000, we have to do this using the .byte operation and
22258 write out special characters outside the quoted string.
22259 Also, the assembler is broken; very long strings are truncated,
22260 so we must artificially break them up early. */
22263 output_ascii (FILE *file, const char *p, int n)
22266 int i, count_string;
22267 const char *for_string = "\t.byte \"";
22268 const char *for_decimal = "\t.byte ";
22269 const char *to_close = NULL;
22272 for (i = 0; i < n; i++)
22275 if (c >= ' ' && c < 0177)
22278 fputs (for_string, file);
22281 /* Write two quotes to get one. */
22289 for_decimal = "\"\n\t.byte ";
22293 if (count_string >= 512)
22295 fputs (to_close, file);
22297 for_string = "\t.byte \"";
22298 for_decimal = "\t.byte ";
22306 fputs (for_decimal, file);
22307 fprintf (file, "%d", c);
22309 for_string = "\n\t.byte \"";
22310 for_decimal = ", ";
22316 /* Now close the string if we have written one. Then end the line. */
22318 fputs (to_close, file);
22321 /* Generate a unique section name for FILENAME for a section type
22322 represented by SECTION_DESC. Output goes into BUF.
22324 SECTION_DESC can be any string, as long as it is different for each
22325 possible section type.
22327 We name the section in the same manner as xlc. The name begins with an
22328 underscore followed by the filename (after stripping any leading directory
22329 names) with the last period replaced by the string SECTION_DESC. If
22330 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22334 rs6000_gen_section_name (char **buf, const char *filename,
22335 const char *section_desc)
22337 const char *q, *after_last_slash, *last_period = 0;
22341 after_last_slash = filename;
22342 for (q = filename; *q; q++)
22345 after_last_slash = q + 1;
22346 else if (*q == '.')
22350 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22351 *buf = (char *) xmalloc (len);
22356 for (q = after_last_slash; *q; q++)
22358 if (q == last_period)
22360 strcpy (p, section_desc);
22361 p += strlen (section_desc);
22365 else if (ISALNUM (*q))
22369 if (last_period == 0)
22370 strcpy (p, section_desc);
22375 /* Emit profile function. */
22378 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22380 /* Non-standard profiling for kernels, which just saves LR then calls
22381 _mcount without worrying about arg saves. The idea is to change
22382 the function prologue as little as possible as it isn't easy to
22383 account for arg save/restore code added just for _mcount. */
22384 if (TARGET_PROFILE_KERNEL)
22387 if (DEFAULT_ABI == ABI_AIX)
22389 #ifndef NO_PROFILE_COUNTERS
22390 # define NO_PROFILE_COUNTERS 0
22392 if (NO_PROFILE_COUNTERS)
22393 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22394 LCT_NORMAL, VOIDmode, 0);
22398 const char *label_name;
22401 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22402 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22403 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22405 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22406 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22409 else if (DEFAULT_ABI == ABI_DARWIN)
22411 const char *mcount_name = RS6000_MCOUNT;
22412 int caller_addr_regno = LR_REGNO;
22414 /* Be conservative and always set this, at least for now. */
22415 crtl->uses_pic_offset_table = 1;
22418 /* For PIC code, set up a stub and collect the caller's address
22419 from r0, which is where the prologue puts it. */
22420 if (MACHOPIC_INDIRECT
22421 && crtl->uses_pic_offset_table)
22422 caller_addr_regno = 0;
22424 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22425 LCT_NORMAL, VOIDmode, 1,
22426 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22430 /* Write function profiler code. */
22433 output_function_profiler (FILE *file, int labelno)
22437 switch (DEFAULT_ABI)
22440 gcc_unreachable ();
22445 warning (0, "no profiling of 64-bit code for this ABI");
22448 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22449 fprintf (file, "\tmflr %s\n", reg_names[0]);
22450 if (NO_PROFILE_COUNTERS)
22452 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22453 reg_names[0], reg_names[1]);
22455 else if (TARGET_SECURE_PLT && flag_pic)
22457 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22458 reg_names[0], reg_names[1]);
22459 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22460 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22461 reg_names[12], reg_names[12]);
22462 assemble_name (file, buf);
22463 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22464 assemble_name (file, buf);
22465 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22467 else if (flag_pic == 1)
22469 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22470 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22471 reg_names[0], reg_names[1]);
22472 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22473 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22474 assemble_name (file, buf);
22475 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22477 else if (flag_pic > 1)
22479 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22480 reg_names[0], reg_names[1]);
22481 /* Now, we need to get the address of the label. */
22482 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22483 assemble_name (file, buf);
22484 fputs ("-.\n1:", file);
22485 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22486 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22487 reg_names[0], reg_names[11]);
22488 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22489 reg_names[0], reg_names[0], reg_names[11]);
22493 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22494 assemble_name (file, buf);
22495 fputs ("@ha\n", file);
22496 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22497 reg_names[0], reg_names[1]);
22498 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22499 assemble_name (file, buf);
22500 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22503 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22504 fprintf (file, "\tbl %s%s\n",
22505 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22510 if (!TARGET_PROFILE_KERNEL)
22512 /* Don't do anything, done in output_profile_hook (). */
22516 gcc_assert (!TARGET_32BIT);
22518 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22519 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22521 if (cfun->static_chain_decl != NULL)
22523 asm_fprintf (file, "\tstd %s,24(%s)\n",
22524 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22525 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22526 asm_fprintf (file, "\tld %s,24(%s)\n",
22527 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22530 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22538 /* The following variable value is the last issued insn. */
22540 static rtx last_scheduled_insn;
22542 /* The following variable helps to balance issuing of load and
22543 store instructions */
22545 static int load_store_pendulum;
22547 /* Power4 load update and store update instructions are cracked into a
22548 load or store and an integer insn which are executed in the same cycle.
22549 Branches have their own dispatch slot which does not count against the
22550 GCC issue rate, but it changes the program flow so there are no other
22551 instructions to issue in this cycle. */
22554 rs6000_variable_issue_1 (rtx insn, int more)
22556 last_scheduled_insn = insn;
22557 if (GET_CODE (PATTERN (insn)) == USE
22558 || GET_CODE (PATTERN (insn)) == CLOBBER)
22560 cached_can_issue_more = more;
22561 return cached_can_issue_more;
22564 if (insn_terminates_group_p (insn, current_group))
22566 cached_can_issue_more = 0;
22567 return cached_can_issue_more;
22570 /* If no reservation, but reach here */
22571 if (recog_memoized (insn) < 0)
22574 if (rs6000_sched_groups)
22576 if (is_microcoded_insn (insn))
22577 cached_can_issue_more = 0;
22578 else if (is_cracked_insn (insn))
22579 cached_can_issue_more = more > 2 ? more - 2 : 0;
22581 cached_can_issue_more = more - 1;
22583 return cached_can_issue_more;
22586 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22589 cached_can_issue_more = more - 1;
22590 return cached_can_issue_more;
22594 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22596 int r = rs6000_variable_issue_1 (insn, more);
22598 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22602 /* Adjust the cost of a scheduling dependency. Return the new cost of
22603 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22606 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22608 enum attr_type attr_type;
22610 if (! recog_memoized (insn))
22613 switch (REG_NOTE_KIND (link))
22617 /* Data dependency; DEP_INSN writes a register that INSN reads
22618 some cycles later. */
22620 /* Separate a load from a narrower, dependent store. */
22621 if (rs6000_sched_groups
22622 && GET_CODE (PATTERN (insn)) == SET
22623 && GET_CODE (PATTERN (dep_insn)) == SET
22624 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22625 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22626 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22627 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22630 attr_type = get_attr_type (insn);
22635 /* Tell the first scheduling pass about the latency between
22636 a mtctr and bctr (and mtlr and br/blr). The first
22637 scheduling pass will not know about this latency since
22638 the mtctr instruction, which has the latency associated
22639 to it, will be generated by reload. */
22640 return TARGET_POWER ? 5 : 4;
22642 /* Leave some extra cycles between a compare and its
22643 dependent branch, to inhibit expensive mispredicts. */
22644 if ((rs6000_cpu_attr == CPU_PPC603
22645 || rs6000_cpu_attr == CPU_PPC604
22646 || rs6000_cpu_attr == CPU_PPC604E
22647 || rs6000_cpu_attr == CPU_PPC620
22648 || rs6000_cpu_attr == CPU_PPC630
22649 || rs6000_cpu_attr == CPU_PPC750
22650 || rs6000_cpu_attr == CPU_PPC7400
22651 || rs6000_cpu_attr == CPU_PPC7450
22652 || rs6000_cpu_attr == CPU_POWER4
22653 || rs6000_cpu_attr == CPU_POWER5
22654 || rs6000_cpu_attr == CPU_POWER7
22655 || rs6000_cpu_attr == CPU_CELL)
22656 && recog_memoized (dep_insn)
22657 && (INSN_CODE (dep_insn) >= 0))
22659 switch (get_attr_type (dep_insn))
22663 case TYPE_DELAYED_COMPARE:
22664 case TYPE_IMUL_COMPARE:
22665 case TYPE_LMUL_COMPARE:
22666 case TYPE_FPCOMPARE:
22667 case TYPE_CR_LOGICAL:
22668 case TYPE_DELAYED_CR:
22677 case TYPE_STORE_UX:
22679 case TYPE_FPSTORE_U:
22680 case TYPE_FPSTORE_UX:
22681 if ((rs6000_cpu == PROCESSOR_POWER6)
22682 && recog_memoized (dep_insn)
22683 && (INSN_CODE (dep_insn) >= 0))
22686 if (GET_CODE (PATTERN (insn)) != SET)
22687 /* If this happens, we have to extend this to schedule
22688 optimally. Return default for now. */
22691 /* Adjust the cost for the case where the value written
22692 by a fixed point operation is used as the address
22693 gen value on a store. */
22694 switch (get_attr_type (dep_insn))
22701 if (! store_data_bypass_p (dep_insn, insn))
22705 case TYPE_LOAD_EXT:
22706 case TYPE_LOAD_EXT_U:
22707 case TYPE_LOAD_EXT_UX:
22708 case TYPE_VAR_SHIFT_ROTATE:
22709 case TYPE_VAR_DELAYED_COMPARE:
22711 if (! store_data_bypass_p (dep_insn, insn))
22717 case TYPE_FAST_COMPARE:
22720 case TYPE_INSERT_WORD:
22721 case TYPE_INSERT_DWORD:
22722 case TYPE_FPLOAD_U:
22723 case TYPE_FPLOAD_UX:
22725 case TYPE_STORE_UX:
22726 case TYPE_FPSTORE_U:
22727 case TYPE_FPSTORE_UX:
22729 if (! store_data_bypass_p (dep_insn, insn))
22737 case TYPE_IMUL_COMPARE:
22738 case TYPE_LMUL_COMPARE:
22740 if (! store_data_bypass_p (dep_insn, insn))
22746 if (! store_data_bypass_p (dep_insn, insn))
22752 if (! store_data_bypass_p (dep_insn, insn))
22765 case TYPE_LOAD_EXT:
22766 case TYPE_LOAD_EXT_U:
22767 case TYPE_LOAD_EXT_UX:
22768 if ((rs6000_cpu == PROCESSOR_POWER6)
22769 && recog_memoized (dep_insn)
22770 && (INSN_CODE (dep_insn) >= 0))
22773 /* Adjust the cost for the case where the value written
22774 by a fixed point instruction is used within the address
22775 gen portion of a subsequent load(u)(x) */
22776 switch (get_attr_type (dep_insn))
22783 if (set_to_load_agen (dep_insn, insn))
22787 case TYPE_LOAD_EXT:
22788 case TYPE_LOAD_EXT_U:
22789 case TYPE_LOAD_EXT_UX:
22790 case TYPE_VAR_SHIFT_ROTATE:
22791 case TYPE_VAR_DELAYED_COMPARE:
22793 if (set_to_load_agen (dep_insn, insn))
22799 case TYPE_FAST_COMPARE:
22802 case TYPE_INSERT_WORD:
22803 case TYPE_INSERT_DWORD:
22804 case TYPE_FPLOAD_U:
22805 case TYPE_FPLOAD_UX:
22807 case TYPE_STORE_UX:
22808 case TYPE_FPSTORE_U:
22809 case TYPE_FPSTORE_UX:
22811 if (set_to_load_agen (dep_insn, insn))
22819 case TYPE_IMUL_COMPARE:
22820 case TYPE_LMUL_COMPARE:
22822 if (set_to_load_agen (dep_insn, insn))
22828 if (set_to_load_agen (dep_insn, insn))
22834 if (set_to_load_agen (dep_insn, insn))
22845 if ((rs6000_cpu == PROCESSOR_POWER6)
22846 && recog_memoized (dep_insn)
22847 && (INSN_CODE (dep_insn) >= 0)
22848 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22855 /* Fall out to return default cost. */
22859 case REG_DEP_OUTPUT:
22860 /* Output dependency; DEP_INSN writes a register that INSN writes some
22862 if ((rs6000_cpu == PROCESSOR_POWER6)
22863 && recog_memoized (dep_insn)
22864 && (INSN_CODE (dep_insn) >= 0))
22866 attr_type = get_attr_type (insn);
22871 if (get_attr_type (dep_insn) == TYPE_FP)
22875 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22883 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22888 gcc_unreachable ();
22894 /* Debug version of rs6000_adjust_cost. */
22897 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22899 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22905 switch (REG_NOTE_KIND (link))
22907 default: dep = "unknown depencency"; break;
22908 case REG_DEP_TRUE: dep = "data dependency"; break;
22909 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22910 case REG_DEP_ANTI: dep = "anti depencency"; break;
22914 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22915 "%s, insn:\n", ret, cost, dep);
22923 /* The function returns a true if INSN is microcoded.
22924 Return false otherwise. */
22927 is_microcoded_insn (rtx insn)
22929 if (!insn || !NONDEBUG_INSN_P (insn)
22930 || GET_CODE (PATTERN (insn)) == USE
22931 || GET_CODE (PATTERN (insn)) == CLOBBER)
22934 if (rs6000_cpu_attr == CPU_CELL)
22935 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22937 if (rs6000_sched_groups)
22939 enum attr_type type = get_attr_type (insn);
22940 if (type == TYPE_LOAD_EXT_U
22941 || type == TYPE_LOAD_EXT_UX
22942 || type == TYPE_LOAD_UX
22943 || type == TYPE_STORE_UX
22944 || type == TYPE_MFCR)
22951 /* The function returns true if INSN is cracked into 2 instructions
22952 by the processor (and therefore occupies 2 issue slots). */
22955 is_cracked_insn (rtx insn)
22957 if (!insn || !NONDEBUG_INSN_P (insn)
22958 || GET_CODE (PATTERN (insn)) == USE
22959 || GET_CODE (PATTERN (insn)) == CLOBBER)
22962 if (rs6000_sched_groups)
22964 enum attr_type type = get_attr_type (insn);
22965 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22966 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22967 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22968 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22969 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22970 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22971 || type == TYPE_IDIV || type == TYPE_LDIV
22972 || type == TYPE_INSERT_WORD)
22979 /* The function returns true if INSN can be issued only from
22980 the branch slot. */
22983 is_branch_slot_insn (rtx insn)
22985 if (!insn || !NONDEBUG_INSN_P (insn)
22986 || GET_CODE (PATTERN (insn)) == USE
22987 || GET_CODE (PATTERN (insn)) == CLOBBER)
22990 if (rs6000_sched_groups)
22992 enum attr_type type = get_attr_type (insn);
22993 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23001 /* The function returns true if out_inst sets a value that is
23002 used in the address generation computation of in_insn */
23004 set_to_load_agen (rtx out_insn, rtx in_insn)
23006 rtx out_set, in_set;
23008 /* For performance reasons, only handle the simple case where
23009 both loads are a single_set. */
23010 out_set = single_set (out_insn);
23013 in_set = single_set (in_insn);
23015 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23021 /* The function returns true if the target storage location of
23022 out_insn is adjacent to the target storage location of in_insn */
23023 /* Return 1 if memory locations are adjacent. */
23026 adjacent_mem_locations (rtx insn1, rtx insn2)
23029 rtx a = get_store_dest (PATTERN (insn1));
23030 rtx b = get_store_dest (PATTERN (insn2));
23032 if ((GET_CODE (XEXP (a, 0)) == REG
23033 || (GET_CODE (XEXP (a, 0)) == PLUS
23034 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23035 && (GET_CODE (XEXP (b, 0)) == REG
23036 || (GET_CODE (XEXP (b, 0)) == PLUS
23037 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23039 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23042 if (GET_CODE (XEXP (a, 0)) == PLUS)
23044 reg0 = XEXP (XEXP (a, 0), 0);
23045 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23048 reg0 = XEXP (a, 0);
23050 if (GET_CODE (XEXP (b, 0)) == PLUS)
23052 reg1 = XEXP (XEXP (b, 0), 0);
23053 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23056 reg1 = XEXP (b, 0);
23058 val_diff = val1 - val0;
23060 return ((REGNO (reg0) == REGNO (reg1))
23061 && ((MEM_SIZE_KNOWN_P (a) && val_diff == MEM_SIZE (a))
23062 || (MEM_SIZE_KNOWN_P (b) && val_diff == -MEM_SIZE (b))));
23068 /* A C statement (sans semicolon) to update the integer scheduling
23069 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23070 INSN earlier, reduce the priority to execute INSN later. Do not
23071 define this macro if you do not need to adjust the scheduling
23072 priorities of insns. */
23075 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23077 /* On machines (like the 750) which have asymmetric integer units,
23078 where one integer unit can do multiply and divides and the other
23079 can't, reduce the priority of multiply/divide so it is scheduled
23080 before other integer operations. */
23083 if (! INSN_P (insn))
23086 if (GET_CODE (PATTERN (insn)) == USE)
23089 switch (rs6000_cpu_attr) {
23091 switch (get_attr_type (insn))
23098 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23099 priority, priority);
23100 if (priority >= 0 && priority < 0x01000000)
23107 if (insn_must_be_first_in_group (insn)
23108 && reload_completed
23109 && current_sched_info->sched_max_insns_priority
23110 && rs6000_sched_restricted_insns_priority)
23113 /* Prioritize insns that can be dispatched only in the first
23115 if (rs6000_sched_restricted_insns_priority == 1)
23116 /* Attach highest priority to insn. This means that in
23117 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23118 precede 'priority' (critical path) considerations. */
23119 return current_sched_info->sched_max_insns_priority;
23120 else if (rs6000_sched_restricted_insns_priority == 2)
23121 /* Increase priority of insn by a minimal amount. This means that in
23122 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23123 considerations precede dispatch-slot restriction considerations. */
23124 return (priority + 1);
23127 if (rs6000_cpu == PROCESSOR_POWER6
23128 && ((load_store_pendulum == -2 && is_load_insn (insn))
23129 || (load_store_pendulum == 2 && is_store_insn (insn))))
23130 /* Attach highest priority to insn if the scheduler has just issued two
23131 stores and this instruction is a load, or two loads and this instruction
23132 is a store. Power6 wants loads and stores scheduled alternately
23134 return current_sched_info->sched_max_insns_priority;
23139 /* Return true if the instruction is nonpipelined on the Cell. */
23141 is_nonpipeline_insn (rtx insn)
23143 enum attr_type type;
23144 if (!insn || !NONDEBUG_INSN_P (insn)
23145 || GET_CODE (PATTERN (insn)) == USE
23146 || GET_CODE (PATTERN (insn)) == CLOBBER)
23149 type = get_attr_type (insn);
23150 if (type == TYPE_IMUL
23151 || type == TYPE_IMUL2
23152 || type == TYPE_IMUL3
23153 || type == TYPE_LMUL
23154 || type == TYPE_IDIV
23155 || type == TYPE_LDIV
23156 || type == TYPE_SDIV
23157 || type == TYPE_DDIV
23158 || type == TYPE_SSQRT
23159 || type == TYPE_DSQRT
23160 || type == TYPE_MFCR
23161 || type == TYPE_MFCRF
23162 || type == TYPE_MFJMPR)
23170 /* Return how many instructions the machine can issue per cycle. */
23173 rs6000_issue_rate (void)
23175 /* Unless scheduling for register pressure, use issue rate of 1 for
23176 first scheduling pass to decrease degradation. */
23177 if (!reload_completed && !flag_sched_pressure)
23180 switch (rs6000_cpu_attr) {
23181 case CPU_RIOS1: /* ? */
23183 case CPU_PPC601: /* ? */
23192 case CPU_PPCE300C2:
23193 case CPU_PPCE300C3:
23194 case CPU_PPCE500MC:
23195 case CPU_PPCE500MC64:
23215 /* Return how many instructions to look ahead for better insn
23219 rs6000_use_sched_lookahead (void)
23221 if (rs6000_cpu_attr == CPU_PPC8540)
23223 if (rs6000_cpu_attr == CPU_CELL)
23224 return (reload_completed ? 8 : 0);
23228 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23230 rs6000_use_sched_lookahead_guard (rtx insn)
23232 if (rs6000_cpu_attr != CPU_CELL)
23235 if (insn == NULL_RTX || !INSN_P (insn))
23238 if (!reload_completed
23239 || is_nonpipeline_insn (insn)
23240 || is_microcoded_insn (insn))
23246 /* Determine is PAT refers to memory. */
23249 is_mem_ref (rtx pat)
23255 /* stack_tie does not produce any real memory traffic. */
23256 if (GET_CODE (pat) == UNSPEC
23257 && XINT (pat, 1) == UNSPEC_TIE)
23260 if (GET_CODE (pat) == MEM)
23263 /* Recursively process the pattern. */
23264 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23266 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23269 ret |= is_mem_ref (XEXP (pat, i));
23270 else if (fmt[i] == 'E')
23271 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23272 ret |= is_mem_ref (XVECEXP (pat, i, j));
23278 /* Determine if PAT is a PATTERN of a load insn. */
23281 is_load_insn1 (rtx pat)
23283 if (!pat || pat == NULL_RTX)
23286 if (GET_CODE (pat) == SET)
23287 return is_mem_ref (SET_SRC (pat));
23289 if (GET_CODE (pat) == PARALLEL)
23293 for (i = 0; i < XVECLEN (pat, 0); i++)
23294 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23301 /* Determine if INSN loads from memory. */
23304 is_load_insn (rtx insn)
23306 if (!insn || !INSN_P (insn))
23309 if (GET_CODE (insn) == CALL_INSN)
23312 return is_load_insn1 (PATTERN (insn));
23315 /* Determine if PAT is a PATTERN of a store insn. */
23318 is_store_insn1 (rtx pat)
23320 if (!pat || pat == NULL_RTX)
23323 if (GET_CODE (pat) == SET)
23324 return is_mem_ref (SET_DEST (pat));
23326 if (GET_CODE (pat) == PARALLEL)
23330 for (i = 0; i < XVECLEN (pat, 0); i++)
23331 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23338 /* Determine if INSN stores to memory. */
23341 is_store_insn (rtx insn)
23343 if (!insn || !INSN_P (insn))
23346 return is_store_insn1 (PATTERN (insn));
23349 /* Return the dest of a store insn. */
23352 get_store_dest (rtx pat)
23354 gcc_assert (is_store_insn1 (pat));
23356 if (GET_CODE (pat) == SET)
23357 return SET_DEST (pat);
23358 else if (GET_CODE (pat) == PARALLEL)
23362 for (i = 0; i < XVECLEN (pat, 0); i++)
23364 rtx inner_pat = XVECEXP (pat, 0, i);
23365 if (GET_CODE (inner_pat) == SET
23366 && is_mem_ref (SET_DEST (inner_pat)))
23370 /* We shouldn't get here, because we should have either a simple
23371 store insn or a store with update which are covered above. */
23375 /* Returns whether the dependence between INSN and NEXT is considered
23376 costly by the given target. */
23379 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23384 /* If the flag is not enabled - no dependence is considered costly;
23385 allow all dependent insns in the same group.
23386 This is the most aggressive option. */
23387 if (rs6000_sched_costly_dep == no_dep_costly)
23390 /* If the flag is set to 1 - a dependence is always considered costly;
23391 do not allow dependent instructions in the same group.
23392 This is the most conservative option. */
23393 if (rs6000_sched_costly_dep == all_deps_costly)
23396 insn = DEP_PRO (dep);
23397 next = DEP_CON (dep);
23399 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23400 && is_load_insn (next)
23401 && is_store_insn (insn))
23402 /* Prevent load after store in the same group. */
23405 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23406 && is_load_insn (next)
23407 && is_store_insn (insn)
23408 && DEP_TYPE (dep) == REG_DEP_TRUE)
23409 /* Prevent load after store in the same group if it is a true
23413 /* The flag is set to X; dependences with latency >= X are considered costly,
23414 and will not be scheduled in the same group. */
23415 if (rs6000_sched_costly_dep <= max_dep_latency
23416 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23422 /* Return the next insn after INSN that is found before TAIL is reached,
23423 skipping any "non-active" insns - insns that will not actually occupy
23424 an issue slot. Return NULL_RTX if such an insn is not found. */
23427 get_next_active_insn (rtx insn, rtx tail)
23429 if (insn == NULL_RTX || insn == tail)
23434 insn = NEXT_INSN (insn);
23435 if (insn == NULL_RTX || insn == tail)
23440 || (NONJUMP_INSN_P (insn)
23441 && GET_CODE (PATTERN (insn)) != USE
23442 && GET_CODE (PATTERN (insn)) != CLOBBER
23443 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23449 /* We are about to begin issuing insns for this clock cycle. */
23452 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23453 rtx *ready ATTRIBUTE_UNUSED,
23454 int *pn_ready ATTRIBUTE_UNUSED,
23455 int clock_var ATTRIBUTE_UNUSED)
23457 int n_ready = *pn_ready;
23460 fprintf (dump, "// rs6000_sched_reorder :\n");
23462 /* Reorder the ready list, if the second to last ready insn
23463 is a nonepipeline insn. */
23464 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23466 if (is_nonpipeline_insn (ready[n_ready - 1])
23467 && (recog_memoized (ready[n_ready - 2]) > 0))
23468 /* Simply swap first two insns. */
23470 rtx tmp = ready[n_ready - 1];
23471 ready[n_ready - 1] = ready[n_ready - 2];
23472 ready[n_ready - 2] = tmp;
23476 if (rs6000_cpu == PROCESSOR_POWER6)
23477 load_store_pendulum = 0;
23479 return rs6000_issue_rate ();
23482 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23485 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23486 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23489 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23491 /* For Power6, we need to handle some special cases to try and keep the
23492 store queue from overflowing and triggering expensive flushes.
23494 This code monitors how load and store instructions are being issued
23495 and skews the ready list one way or the other to increase the likelihood
23496 that a desired instruction is issued at the proper time.
23498 A couple of things are done. First, we maintain a "load_store_pendulum"
23499 to track the current state of load/store issue.
23501 - If the pendulum is at zero, then no loads or stores have been
23502 issued in the current cycle so we do nothing.
23504 - If the pendulum is 1, then a single load has been issued in this
23505 cycle and we attempt to locate another load in the ready list to
23508 - If the pendulum is -2, then two stores have already been
23509 issued in this cycle, so we increase the priority of the first load
23510 in the ready list to increase it's likelihood of being chosen first
23513 - If the pendulum is -1, then a single store has been issued in this
23514 cycle and we attempt to locate another store in the ready list to
23515 issue with it, preferring a store to an adjacent memory location to
23516 facilitate store pairing in the store queue.
23518 - If the pendulum is 2, then two loads have already been
23519 issued in this cycle, so we increase the priority of the first store
23520 in the ready list to increase it's likelihood of being chosen first
23523 - If the pendulum < -2 or > 2, then do nothing.
23525 Note: This code covers the most common scenarios. There exist non
23526 load/store instructions which make use of the LSU and which
23527 would need to be accounted for to strictly model the behavior
23528 of the machine. Those instructions are currently unaccounted
23529 for to help minimize compile time overhead of this code.
23531 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23537 if (is_store_insn (last_scheduled_insn))
23538 /* Issuing a store, swing the load_store_pendulum to the left */
23539 load_store_pendulum--;
23540 else if (is_load_insn (last_scheduled_insn))
23541 /* Issuing a load, swing the load_store_pendulum to the right */
23542 load_store_pendulum++;
23544 return cached_can_issue_more;
23546 /* If the pendulum is balanced, or there is only one instruction on
23547 the ready list, then all is well, so return. */
23548 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23549 return cached_can_issue_more;
23551 if (load_store_pendulum == 1)
23553 /* A load has been issued in this cycle. Scan the ready list
23554 for another load to issue with it */
23559 if (is_load_insn (ready[pos]))
23561 /* Found a load. Move it to the head of the ready list,
23562 and adjust it's priority so that it is more likely to
23565 for (i=pos; i<*pn_ready-1; i++)
23566 ready[i] = ready[i + 1];
23567 ready[*pn_ready-1] = tmp;
23569 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23570 INSN_PRIORITY (tmp)++;
23576 else if (load_store_pendulum == -2)
23578 /* Two stores have been issued in this cycle. Increase the
23579 priority of the first load in the ready list to favor it for
23580 issuing in the next cycle. */
23585 if (is_load_insn (ready[pos])
23587 && INSN_PRIORITY_KNOWN (ready[pos]))
23589 INSN_PRIORITY (ready[pos])++;
23591 /* Adjust the pendulum to account for the fact that a load
23592 was found and increased in priority. This is to prevent
23593 increasing the priority of multiple loads */
23594 load_store_pendulum--;
23601 else if (load_store_pendulum == -1)
23603 /* A store has been issued in this cycle. Scan the ready list for
23604 another store to issue with it, preferring a store to an adjacent
23606 int first_store_pos = -1;
23612 if (is_store_insn (ready[pos]))
23614 /* Maintain the index of the first store found on the
23616 if (first_store_pos == -1)
23617 first_store_pos = pos;
23619 if (is_store_insn (last_scheduled_insn)
23620 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23622 /* Found an adjacent store. Move it to the head of the
23623 ready list, and adjust it's priority so that it is
23624 more likely to stay there */
23626 for (i=pos; i<*pn_ready-1; i++)
23627 ready[i] = ready[i + 1];
23628 ready[*pn_ready-1] = tmp;
23630 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23631 INSN_PRIORITY (tmp)++;
23633 first_store_pos = -1;
23641 if (first_store_pos >= 0)
23643 /* An adjacent store wasn't found, but a non-adjacent store was,
23644 so move the non-adjacent store to the front of the ready
23645 list, and adjust its priority so that it is more likely to
23647 tmp = ready[first_store_pos];
23648 for (i=first_store_pos; i<*pn_ready-1; i++)
23649 ready[i] = ready[i + 1];
23650 ready[*pn_ready-1] = tmp;
23651 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23652 INSN_PRIORITY (tmp)++;
23655 else if (load_store_pendulum == 2)
23657 /* Two loads have been issued in this cycle. Increase the priority
23658 of the first store in the ready list to favor it for issuing in
23664 if (is_store_insn (ready[pos])
23666 && INSN_PRIORITY_KNOWN (ready[pos]))
23668 INSN_PRIORITY (ready[pos])++;
23670 /* Adjust the pendulum to account for the fact that a store
23671 was found and increased in priority. This is to prevent
23672 increasing the priority of multiple stores */
23673 load_store_pendulum++;
23682 return cached_can_issue_more;
23685 /* Return whether the presence of INSN causes a dispatch group termination
23686 of group WHICH_GROUP.
23688 If WHICH_GROUP == current_group, this function will return true if INSN
23689 causes the termination of the current group (i.e, the dispatch group to
23690 which INSN belongs). This means that INSN will be the last insn in the
23691 group it belongs to.
23693 If WHICH_GROUP == previous_group, this function will return true if INSN
23694 causes the termination of the previous group (i.e, the dispatch group that
23695 precedes the group to which INSN belongs). This means that INSN will be
23696 the first insn in the group it belongs to). */
23699 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23706 first = insn_must_be_first_in_group (insn);
23707 last = insn_must_be_last_in_group (insn);
23712 if (which_group == current_group)
23714 else if (which_group == previous_group)
23722 insn_must_be_first_in_group (rtx insn)
23724 enum attr_type type;
23727 || GET_CODE (insn) == NOTE
23728 || DEBUG_INSN_P (insn)
23729 || GET_CODE (PATTERN (insn)) == USE
23730 || GET_CODE (PATTERN (insn)) == CLOBBER)
23733 switch (rs6000_cpu)
23735 case PROCESSOR_POWER5:
23736 if (is_cracked_insn (insn))
23738 case PROCESSOR_POWER4:
23739 if (is_microcoded_insn (insn))
23742 if (!rs6000_sched_groups)
23745 type = get_attr_type (insn);
23752 case TYPE_DELAYED_CR:
23753 case TYPE_CR_LOGICAL:
23767 case PROCESSOR_POWER6:
23768 type = get_attr_type (insn);
23772 case TYPE_INSERT_DWORD:
23776 case TYPE_VAR_SHIFT_ROTATE:
23783 case TYPE_INSERT_WORD:
23784 case TYPE_DELAYED_COMPARE:
23785 case TYPE_IMUL_COMPARE:
23786 case TYPE_LMUL_COMPARE:
23787 case TYPE_FPCOMPARE:
23798 case TYPE_LOAD_EXT_UX:
23800 case TYPE_STORE_UX:
23801 case TYPE_FPLOAD_U:
23802 case TYPE_FPLOAD_UX:
23803 case TYPE_FPSTORE_U:
23804 case TYPE_FPSTORE_UX:
23810 case PROCESSOR_POWER7:
23811 type = get_attr_type (insn);
23815 case TYPE_CR_LOGICAL:
23822 case TYPE_DELAYED_COMPARE:
23823 case TYPE_VAR_DELAYED_COMPARE:
23829 case TYPE_LOAD_EXT:
23830 case TYPE_LOAD_EXT_U:
23831 case TYPE_LOAD_EXT_UX:
23833 case TYPE_STORE_UX:
23834 case TYPE_FPLOAD_U:
23835 case TYPE_FPLOAD_UX:
23836 case TYPE_FPSTORE_U:
23837 case TYPE_FPSTORE_UX:
23853 insn_must_be_last_in_group (rtx insn)
23855 enum attr_type type;
23858 || GET_CODE (insn) == NOTE
23859 || DEBUG_INSN_P (insn)
23860 || GET_CODE (PATTERN (insn)) == USE
23861 || GET_CODE (PATTERN (insn)) == CLOBBER)
23864 switch (rs6000_cpu) {
23865 case PROCESSOR_POWER4:
23866 case PROCESSOR_POWER5:
23867 if (is_microcoded_insn (insn))
23870 if (is_branch_slot_insn (insn))
23874 case PROCESSOR_POWER6:
23875 type = get_attr_type (insn);
23882 case TYPE_VAR_SHIFT_ROTATE:
23889 case TYPE_DELAYED_COMPARE:
23890 case TYPE_IMUL_COMPARE:
23891 case TYPE_LMUL_COMPARE:
23892 case TYPE_FPCOMPARE:
23906 case PROCESSOR_POWER7:
23907 type = get_attr_type (insn);
23915 case TYPE_LOAD_EXT_U:
23916 case TYPE_LOAD_EXT_UX:
23917 case TYPE_STORE_UX:
23930 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23931 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23934 is_costly_group (rtx *group_insns, rtx next_insn)
23937 int issue_rate = rs6000_issue_rate ();
23939 for (i = 0; i < issue_rate; i++)
23941 sd_iterator_def sd_it;
23943 rtx insn = group_insns[i];
23948 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23950 rtx next = DEP_CON (dep);
23952 if (next == next_insn
23953 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23961 /* Utility of the function redefine_groups.
23962 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23963 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23964 to keep it "far" (in a separate group) from GROUP_INSNS, following
23965 one of the following schemes, depending on the value of the flag
23966 -minsert_sched_nops = X:
23967 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23968 in order to force NEXT_INSN into a separate group.
23969 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23970 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23971 insertion (has a group just ended, how many vacant issue slots remain in the
23972 last group, and how many dispatch groups were encountered so far). */
23975 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23976 rtx next_insn, bool *group_end, int can_issue_more,
23981 int issue_rate = rs6000_issue_rate ();
23982 bool end = *group_end;
23985 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23986 return can_issue_more;
23988 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23989 return can_issue_more;
23991 force = is_costly_group (group_insns, next_insn);
23993 return can_issue_more;
23995 if (sched_verbose > 6)
23996 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23997 *group_count ,can_issue_more);
23999 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24002 can_issue_more = 0;
24004 /* Since only a branch can be issued in the last issue_slot, it is
24005 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24006 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24007 in this case the last nop will start a new group and the branch
24008 will be forced to the new group. */
24009 if (can_issue_more && !is_branch_slot_insn (next_insn))
24012 while (can_issue_more > 0)
24015 emit_insn_before (nop, next_insn);
24023 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24025 int n_nops = rs6000_sched_insert_nops;
24027 /* Nops can't be issued from the branch slot, so the effective
24028 issue_rate for nops is 'issue_rate - 1'. */
24029 if (can_issue_more == 0)
24030 can_issue_more = issue_rate;
24032 if (can_issue_more == 0)
24034 can_issue_more = issue_rate - 1;
24037 for (i = 0; i < issue_rate; i++)
24039 group_insns[i] = 0;
24046 emit_insn_before (nop, next_insn);
24047 if (can_issue_more == issue_rate - 1) /* new group begins */
24050 if (can_issue_more == 0)
24052 can_issue_more = issue_rate - 1;
24055 for (i = 0; i < issue_rate; i++)
24057 group_insns[i] = 0;
24063 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24066 /* Is next_insn going to start a new group? */
24069 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24070 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24071 || (can_issue_more < issue_rate &&
24072 insn_terminates_group_p (next_insn, previous_group)));
24073 if (*group_end && end)
24076 if (sched_verbose > 6)
24077 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24078 *group_count, can_issue_more);
24079 return can_issue_more;
24082 return can_issue_more;
24085 /* This function tries to synch the dispatch groups that the compiler "sees"
24086 with the dispatch groups that the processor dispatcher is expected to
24087 form in practice. It tries to achieve this synchronization by forcing the
24088 estimated processor grouping on the compiler (as opposed to the function
24089 'pad_goups' which tries to force the scheduler's grouping on the processor).
24091 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24092 examines the (estimated) dispatch groups that will be formed by the processor
24093 dispatcher. It marks these group boundaries to reflect the estimated
24094 processor grouping, overriding the grouping that the scheduler had marked.
24095 Depending on the value of the flag '-minsert-sched-nops' this function can
24096 force certain insns into separate groups or force a certain distance between
24097 them by inserting nops, for example, if there exists a "costly dependence"
24100 The function estimates the group boundaries that the processor will form as
24101 follows: It keeps track of how many vacant issue slots are available after
24102 each insn. A subsequent insn will start a new group if one of the following
24104 - no more vacant issue slots remain in the current dispatch group.
24105 - only the last issue slot, which is the branch slot, is vacant, but the next
24106 insn is not a branch.
24107 - only the last 2 or less issue slots, including the branch slot, are vacant,
24108 which means that a cracked insn (which occupies two issue slots) can't be
24109 issued in this group.
24110 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24111 start a new group. */
24114 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24116 rtx insn, next_insn;
24118 int can_issue_more;
24121 int group_count = 0;
24125 issue_rate = rs6000_issue_rate ();
24126 group_insns = XALLOCAVEC (rtx, issue_rate);
24127 for (i = 0; i < issue_rate; i++)
24129 group_insns[i] = 0;
24131 can_issue_more = issue_rate;
24133 insn = get_next_active_insn (prev_head_insn, tail);
24136 while (insn != NULL_RTX)
24138 slot = (issue_rate - can_issue_more);
24139 group_insns[slot] = insn;
24141 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24142 if (insn_terminates_group_p (insn, current_group))
24143 can_issue_more = 0;
24145 next_insn = get_next_active_insn (insn, tail);
24146 if (next_insn == NULL_RTX)
24147 return group_count + 1;
24149 /* Is next_insn going to start a new group? */
24151 = (can_issue_more == 0
24152 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24153 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24154 || (can_issue_more < issue_rate &&
24155 insn_terminates_group_p (next_insn, previous_group)));
24157 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24158 next_insn, &group_end, can_issue_more,
24164 can_issue_more = 0;
24165 for (i = 0; i < issue_rate; i++)
24167 group_insns[i] = 0;
24171 if (GET_MODE (next_insn) == TImode && can_issue_more)
24172 PUT_MODE (next_insn, VOIDmode);
24173 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24174 PUT_MODE (next_insn, TImode);
24177 if (can_issue_more == 0)
24178 can_issue_more = issue_rate;
24181 return group_count;
24184 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24185 dispatch group boundaries that the scheduler had marked. Pad with nops
24186 any dispatch groups which have vacant issue slots, in order to force the
24187 scheduler's grouping on the processor dispatcher. The function
24188 returns the number of dispatch groups found. */
24191 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24193 rtx insn, next_insn;
24196 int can_issue_more;
24198 int group_count = 0;
24200 /* Initialize issue_rate. */
24201 issue_rate = rs6000_issue_rate ();
24202 can_issue_more = issue_rate;
24204 insn = get_next_active_insn (prev_head_insn, tail);
24205 next_insn = get_next_active_insn (insn, tail);
24207 while (insn != NULL_RTX)
24210 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24212 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24214 if (next_insn == NULL_RTX)
24219 /* If the scheduler had marked group termination at this location
24220 (between insn and next_insn), and neither insn nor next_insn will
24221 force group termination, pad the group with nops to force group
24224 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24225 && !insn_terminates_group_p (insn, current_group)
24226 && !insn_terminates_group_p (next_insn, previous_group))
24228 if (!is_branch_slot_insn (next_insn))
24231 while (can_issue_more)
24234 emit_insn_before (nop, next_insn);
24239 can_issue_more = issue_rate;
24244 next_insn = get_next_active_insn (insn, tail);
24247 return group_count;
24250 /* We're beginning a new block. Initialize data structures as necessary. */
24253 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24254 int sched_verbose ATTRIBUTE_UNUSED,
24255 int max_ready ATTRIBUTE_UNUSED)
24257 last_scheduled_insn = NULL_RTX;
24258 load_store_pendulum = 0;
24261 /* The following function is called at the end of scheduling BB.
24262 After reload, it inserts nops at insn group bundling. */
24265 rs6000_sched_finish (FILE *dump, int sched_verbose)
24270 fprintf (dump, "=== Finishing schedule.\n");
24272 if (reload_completed && rs6000_sched_groups)
24274 /* Do not run sched_finish hook when selective scheduling enabled. */
24275 if (sel_sched_p ())
24278 if (rs6000_sched_insert_nops == sched_finish_none)
24281 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24282 n_groups = pad_groups (dump, sched_verbose,
24283 current_sched_info->prev_head,
24284 current_sched_info->next_tail);
24286 n_groups = redefine_groups (dump, sched_verbose,
24287 current_sched_info->prev_head,
24288 current_sched_info->next_tail);
24290 if (sched_verbose >= 6)
24292 fprintf (dump, "ngroups = %d\n", n_groups);
24293 print_rtl (dump, current_sched_info->prev_head);
24294 fprintf (dump, "Done finish_sched\n");
24299 struct _rs6000_sched_context
24301 short cached_can_issue_more;
24302 rtx last_scheduled_insn;
24303 int load_store_pendulum;
24306 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24307 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24309 /* Allocate store for new scheduling context. */
24311 rs6000_alloc_sched_context (void)
24313 return xmalloc (sizeof (rs6000_sched_context_def));
24316 /* If CLEAN_P is true then initializes _SC with clean data,
24317 and from the global context otherwise. */
24319 rs6000_init_sched_context (void *_sc, bool clean_p)
24321 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24325 sc->cached_can_issue_more = 0;
24326 sc->last_scheduled_insn = NULL_RTX;
24327 sc->load_store_pendulum = 0;
24331 sc->cached_can_issue_more = cached_can_issue_more;
24332 sc->last_scheduled_insn = last_scheduled_insn;
24333 sc->load_store_pendulum = load_store_pendulum;
24337 /* Sets the global scheduling context to the one pointed to by _SC. */
24339 rs6000_set_sched_context (void *_sc)
24341 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24343 gcc_assert (sc != NULL);
24345 cached_can_issue_more = sc->cached_can_issue_more;
24346 last_scheduled_insn = sc->last_scheduled_insn;
24347 load_store_pendulum = sc->load_store_pendulum;
24352 rs6000_free_sched_context (void *_sc)
24354 gcc_assert (_sc != NULL);
24360 /* Length in units of the trampoline for entering a nested function. */
24363 rs6000_trampoline_size (void)
24367 switch (DEFAULT_ABI)
24370 gcc_unreachable ();
24373 ret = (TARGET_32BIT) ? 12 : 24;
24378 ret = (TARGET_32BIT) ? 40 : 48;
24385 /* Emit RTL insns to initialize the variable parts of a trampoline.
24386 FNADDR is an RTX for the address of the function's pure code.
24387 CXT is an RTX for the static chain value for the function. */
24390 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24392 int regsize = (TARGET_32BIT) ? 4 : 8;
24393 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24394 rtx ctx_reg = force_reg (Pmode, cxt);
24395 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24397 switch (DEFAULT_ABI)
24400 gcc_unreachable ();
24402 /* Under AIX, just build the 3 word function descriptor */
24405 rtx fnmem, fn_reg, toc_reg;
24407 if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS)
24408 error ("-mno-r11 must not be used if you have trampolines");
24410 fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24411 fn_reg = gen_reg_rtx (Pmode);
24412 toc_reg = gen_reg_rtx (Pmode);
24414 /* Macro to shorten the code expansions below. */
24415 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24417 m_tramp = replace_equiv_address (m_tramp, addr);
24419 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24420 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24421 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24422 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24423 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24429 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24432 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24433 LCT_NORMAL, VOIDmode, 4,
24435 GEN_INT (rs6000_trampoline_size ()), SImode,
24443 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24444 identifier as an argument, so the front end shouldn't look it up. */
24447 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24449 return is_attribute_p ("altivec", attr_id);
24452 /* Handle the "altivec" attribute. The attribute may have
24453 arguments as follows:
24455 __attribute__((altivec(vector__)))
24456 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24457 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24459 and may appear more than once (e.g., 'vector bool char') in a
24460 given declaration. */
24463 rs6000_handle_altivec_attribute (tree *node,
24464 tree name ATTRIBUTE_UNUSED,
24466 int flags ATTRIBUTE_UNUSED,
24467 bool *no_add_attrs)
24469 tree type = *node, result = NULL_TREE;
24470 enum machine_mode mode;
24473 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24474 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24475 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24478 while (POINTER_TYPE_P (type)
24479 || TREE_CODE (type) == FUNCTION_TYPE
24480 || TREE_CODE (type) == METHOD_TYPE
24481 || TREE_CODE (type) == ARRAY_TYPE)
24482 type = TREE_TYPE (type);
24484 mode = TYPE_MODE (type);
24486 /* Check for invalid AltiVec type qualifiers. */
24487 if (type == long_double_type_node)
24488 error ("use of %<long double%> in AltiVec types is invalid");
24489 else if (type == boolean_type_node)
24490 error ("use of boolean types in AltiVec types is invalid");
24491 else if (TREE_CODE (type) == COMPLEX_TYPE)
24492 error ("use of %<complex%> in AltiVec types is invalid");
24493 else if (DECIMAL_FLOAT_MODE_P (mode))
24494 error ("use of decimal floating point types in AltiVec types is invalid");
24495 else if (!TARGET_VSX)
24497 if (type == long_unsigned_type_node || type == long_integer_type_node)
24500 error ("use of %<long%> in AltiVec types is invalid for "
24501 "64-bit code without -mvsx");
24502 else if (rs6000_warn_altivec_long)
24503 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24506 else if (type == long_long_unsigned_type_node
24507 || type == long_long_integer_type_node)
24508 error ("use of %<long long%> in AltiVec types is invalid without "
24510 else if (type == double_type_node)
24511 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24514 switch (altivec_type)
24517 unsigned_p = TYPE_UNSIGNED (type);
24521 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24524 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24527 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24530 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24532 case SFmode: result = V4SF_type_node; break;
24533 case DFmode: result = V2DF_type_node; break;
24534 /* If the user says 'vector int bool', we may be handed the 'bool'
24535 attribute _before_ the 'vector' attribute, and so select the
24536 proper type in the 'b' case below. */
24537 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24538 case V2DImode: case V2DFmode:
24546 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24547 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24548 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24549 case QImode: case V16QImode: result = bool_V16QI_type_node;
24556 case V8HImode: result = pixel_V8HI_type_node;
24562 /* Propagate qualifiers attached to the element type
24563 onto the vector type. */
24564 if (result && result != type && TYPE_QUALS (type))
24565 result = build_qualified_type (result, TYPE_QUALS (type));
24567 *no_add_attrs = true; /* No need to hang on to the attribute. */
24570 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24575 /* AltiVec defines four built-in scalar types that serve as vector
24576 elements; we must teach the compiler how to mangle them. */
24578 static const char *
24579 rs6000_mangle_type (const_tree type)
24581 type = TYPE_MAIN_VARIANT (type);
24583 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24584 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24587 if (type == bool_char_type_node) return "U6__boolc";
24588 if (type == bool_short_type_node) return "U6__bools";
24589 if (type == pixel_type_node) return "u7__pixel";
24590 if (type == bool_int_type_node) return "U6__booli";
24591 if (type == bool_long_type_node) return "U6__booll";
24593 /* Mangle IBM extended float long double as `g' (__float128) on
24594 powerpc*-linux where long-double-64 previously was the default. */
24595 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24597 && TARGET_LONG_DOUBLE_128
24598 && !TARGET_IEEEQUAD)
24601 /* For all other types, use normal C++ mangling. */
24605 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24606 struct attribute_spec.handler. */
24609 rs6000_handle_longcall_attribute (tree *node, tree name,
24610 tree args ATTRIBUTE_UNUSED,
24611 int flags ATTRIBUTE_UNUSED,
24612 bool *no_add_attrs)
24614 if (TREE_CODE (*node) != FUNCTION_TYPE
24615 && TREE_CODE (*node) != FIELD_DECL
24616 && TREE_CODE (*node) != TYPE_DECL)
24618 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24620 *no_add_attrs = true;
24626 /* Set longcall attributes on all functions declared when
24627 rs6000_default_long_calls is true. */
24629 rs6000_set_default_type_attributes (tree type)
24631 if (rs6000_default_long_calls
24632 && (TREE_CODE (type) == FUNCTION_TYPE
24633 || TREE_CODE (type) == METHOD_TYPE))
24634 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24636 TYPE_ATTRIBUTES (type));
24639 darwin_set_default_type_attributes (type);
24643 /* Return a reference suitable for calling a function with the
24644 longcall attribute. */
24647 rs6000_longcall_ref (rtx call_ref)
24649 const char *call_name;
24652 if (GET_CODE (call_ref) != SYMBOL_REF)
24655 /* System V adds '.' to the internal name, so skip them. */
24656 call_name = XSTR (call_ref, 0);
24657 if (*call_name == '.')
24659 while (*call_name == '.')
24662 node = get_identifier (call_name);
24663 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24666 return force_reg (Pmode, call_ref);
24669 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24670 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24673 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24674 struct attribute_spec.handler. */
24676 rs6000_handle_struct_attribute (tree *node, tree name,
24677 tree args ATTRIBUTE_UNUSED,
24678 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24681 if (DECL_P (*node))
24683 if (TREE_CODE (*node) == TYPE_DECL)
24684 type = &TREE_TYPE (*node);
24689 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24690 || TREE_CODE (*type) == UNION_TYPE)))
24692 warning (OPT_Wattributes, "%qE attribute ignored", name);
24693 *no_add_attrs = true;
24696 else if ((is_attribute_p ("ms_struct", name)
24697 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24698 || ((is_attribute_p ("gcc_struct", name)
24699 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24701 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24703 *no_add_attrs = true;
24710 rs6000_ms_bitfield_layout_p (const_tree record_type)
24712 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24713 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24714 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24717 #ifdef USING_ELFOS_H
24719 /* A get_unnamed_section callback, used for switching to toc_section. */
24722 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24724 if (DEFAULT_ABI == ABI_AIX
24725 && TARGET_MINIMAL_TOC
24726 && !TARGET_RELOCATABLE)
24728 if (!toc_initialized)
24730 toc_initialized = 1;
24731 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24732 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24733 fprintf (asm_out_file, "\t.tc ");
24734 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24735 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24736 fprintf (asm_out_file, "\n");
24738 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24739 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24740 fprintf (asm_out_file, " = .+32768\n");
24743 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24745 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24746 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24749 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24750 if (!toc_initialized)
24752 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24753 fprintf (asm_out_file, " = .+32768\n");
24754 toc_initialized = 1;
24759 /* Implement TARGET_ASM_INIT_SECTIONS. */
24762 rs6000_elf_asm_init_sections (void)
24765 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24768 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24769 SDATA2_SECTION_ASM_OP);
24772 /* Implement TARGET_SELECT_RTX_SECTION. */
24775 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24776 unsigned HOST_WIDE_INT align)
24778 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24779 return toc_section;
24781 return default_elf_select_rtx_section (mode, x, align);
24784 /* For a SYMBOL_REF, set generic flags and then perform some
24785 target-specific processing.
24787 When the AIX ABI is requested on a non-AIX system, replace the
24788 function name with the real name (with a leading .) rather than the
24789 function descriptor name. This saves a lot of overriding code to
24790 read the prefixes. */
24793 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24795 default_encode_section_info (decl, rtl, first);
24798 && TREE_CODE (decl) == FUNCTION_DECL
24800 && DEFAULT_ABI == ABI_AIX)
24802 rtx sym_ref = XEXP (rtl, 0);
24803 size_t len = strlen (XSTR (sym_ref, 0));
24804 char *str = XALLOCAVEC (char, len + 2);
24806 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24807 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24812 compare_section_name (const char *section, const char *templ)
24816 len = strlen (templ);
24817 return (strncmp (section, templ, len) == 0
24818 && (section[len] == 0 || section[len] == '.'));
24822 rs6000_elf_in_small_data_p (const_tree decl)
24824 if (rs6000_sdata == SDATA_NONE)
24827 /* We want to merge strings, so we never consider them small data. */
24828 if (TREE_CODE (decl) == STRING_CST)
24831 /* Functions are never in the small data area. */
24832 if (TREE_CODE (decl) == FUNCTION_DECL)
24835 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24837 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24838 if (compare_section_name (section, ".sdata")
24839 || compare_section_name (section, ".sdata2")
24840 || compare_section_name (section, ".gnu.linkonce.s")
24841 || compare_section_name (section, ".sbss")
24842 || compare_section_name (section, ".sbss2")
24843 || compare_section_name (section, ".gnu.linkonce.sb")
24844 || strcmp (section, ".PPC.EMB.sdata0") == 0
24845 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24850 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24853 && size <= g_switch_value
24854 /* If it's not public, and we're not going to reference it there,
24855 there's no need to put it in the small data section. */
24856 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24863 #endif /* USING_ELFOS_H */
24865 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24868 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24870 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24873 /* Return a REG that occurs in ADDR with coefficient 1.
24874 ADDR can be effectively incremented by incrementing REG.
24876 r0 is special and we must not select it as an address
24877 register by this routine since our caller will try to
24878 increment the returned register via an "la" instruction. */
24881 find_addr_reg (rtx addr)
24883 while (GET_CODE (addr) == PLUS)
24885 if (GET_CODE (XEXP (addr, 0)) == REG
24886 && REGNO (XEXP (addr, 0)) != 0)
24887 addr = XEXP (addr, 0);
24888 else if (GET_CODE (XEXP (addr, 1)) == REG
24889 && REGNO (XEXP (addr, 1)) != 0)
24890 addr = XEXP (addr, 1);
24891 else if (CONSTANT_P (XEXP (addr, 0)))
24892 addr = XEXP (addr, 1);
24893 else if (CONSTANT_P (XEXP (addr, 1)))
24894 addr = XEXP (addr, 0);
24896 gcc_unreachable ();
24898 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24903 rs6000_fatal_bad_address (rtx op)
24905 fatal_insn ("bad address", op);
24910 typedef struct branch_island_d {
24911 tree function_name;
24916 DEF_VEC_O(branch_island);
24917 DEF_VEC_ALLOC_O(branch_island,gc);
24919 static VEC(branch_island,gc) *branch_islands;
24921 /* Remember to generate a branch island for far calls to the given
24925 add_compiler_branch_island (tree label_name, tree function_name,
24928 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24930 bi->function_name = function_name;
24931 bi->label_name = label_name;
24932 bi->line_number = line_number;
24935 /* Generate far-jump branch islands for everything recorded in
24936 branch_islands. Invoked immediately after the last instruction of
24937 the epilogue has been emitted; the branch islands must be appended
24938 to, and contiguous with, the function body. Mach-O stubs are
24939 generated in machopic_output_stub(). */
24942 macho_branch_islands (void)
24946 while (!VEC_empty (branch_island, branch_islands))
24948 branch_island *bi = VEC_last (branch_island, branch_islands);
24949 const char *label = IDENTIFIER_POINTER (bi->label_name);
24950 const char *name = IDENTIFIER_POINTER (bi->function_name);
24951 char name_buf[512];
24952 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24953 if (name[0] == '*' || name[0] == '&')
24954 strcpy (name_buf, name+1);
24958 strcpy (name_buf+1, name);
24960 strcpy (tmp_buf, "\n");
24961 strcat (tmp_buf, label);
24962 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24963 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24964 dbxout_stabd (N_SLINE, bi->line_number);
24965 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24968 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24969 strcat (tmp_buf, label);
24970 strcat (tmp_buf, "_pic\n");
24971 strcat (tmp_buf, label);
24972 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24974 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24975 strcat (tmp_buf, name_buf);
24976 strcat (tmp_buf, " - ");
24977 strcat (tmp_buf, label);
24978 strcat (tmp_buf, "_pic)\n");
24980 strcat (tmp_buf, "\tmtlr r0\n");
24982 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24983 strcat (tmp_buf, name_buf);
24984 strcat (tmp_buf, " - ");
24985 strcat (tmp_buf, label);
24986 strcat (tmp_buf, "_pic)\n");
24988 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24992 strcat (tmp_buf, ":\nlis r12,hi16(");
24993 strcat (tmp_buf, name_buf);
24994 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24995 strcat (tmp_buf, name_buf);
24996 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24998 output_asm_insn (tmp_buf, 0);
24999 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25000 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25001 dbxout_stabd (N_SLINE, bi->line_number);
25002 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25003 VEC_pop (branch_island, branch_islands);
25007 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25008 already there or not. */
25011 no_previous_def (tree function_name)
25016 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25017 if (function_name == bi->function_name)
25022 /* GET_PREV_LABEL gets the label name from the previous definition of
25026 get_prev_label (tree function_name)
25031 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25032 if (function_name == bi->function_name)
25033 return bi->label_name;
25037 /* INSN is either a function call or a millicode call. It may have an
25038 unconditional jump in its delay slot.
25040 CALL_DEST is the routine we are calling. */
25043 output_call (rtx insn, rtx *operands, int dest_operand_number,
25044 int cookie_operand_number)
25046 static char buf[256];
25047 if (darwin_emit_branch_islands
25048 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25049 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25052 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25054 if (no_previous_def (funname))
25056 rtx label_rtx = gen_label_rtx ();
25057 char *label_buf, temp_buf[256];
25058 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25059 CODE_LABEL_NUMBER (label_rtx));
25060 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25061 labelname = get_identifier (label_buf);
25062 add_compiler_branch_island (labelname, funname, insn_line (insn));
25065 labelname = get_prev_label (funname);
25067 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25068 instruction will reach 'foo', otherwise link as 'bl L42'".
25069 "L42" should be a 'branch island', that will do a far jump to
25070 'foo'. Branch islands are generated in
25071 macho_branch_islands(). */
25072 sprintf (buf, "jbsr %%z%d,%.246s",
25073 dest_operand_number, IDENTIFIER_POINTER (labelname));
25076 sprintf (buf, "bl %%z%d", dest_operand_number);
25080 /* Generate PIC and indirect symbol stubs. */
25083 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25085 unsigned int length;
25086 char *symbol_name, *lazy_ptr_name;
25087 char *local_label_0;
25088 static int label = 0;
25090 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25091 symb = (*targetm.strip_name_encoding) (symb);
25094 length = strlen (symb);
25095 symbol_name = XALLOCAVEC (char, length + 32);
25096 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25098 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25099 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25102 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25104 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25108 fprintf (file, "\t.align 5\n");
25110 fprintf (file, "%s:\n", stub);
25111 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25114 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25115 sprintf (local_label_0, "\"L%011d$spb\"", label);
25117 fprintf (file, "\tmflr r0\n");
25118 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25119 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25120 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25121 lazy_ptr_name, local_label_0);
25122 fprintf (file, "\tmtlr r0\n");
25123 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25124 (TARGET_64BIT ? "ldu" : "lwzu"),
25125 lazy_ptr_name, local_label_0);
25126 fprintf (file, "\tmtctr r12\n");
25127 fprintf (file, "\tbctr\n");
25131 fprintf (file, "\t.align 4\n");
25133 fprintf (file, "%s:\n", stub);
25134 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25136 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25137 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25138 (TARGET_64BIT ? "ldu" : "lwzu"),
25140 fprintf (file, "\tmtctr r12\n");
25141 fprintf (file, "\tbctr\n");
25144 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25145 fprintf (file, "%s:\n", lazy_ptr_name);
25146 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25147 fprintf (file, "%sdyld_stub_binding_helper\n",
25148 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25151 /* Legitimize PIC addresses. If the address is already
25152 position-independent, we return ORIG. Newly generated
25153 position-independent addresses go into a reg. This is REG if non
25154 zero, otherwise we allocate register(s) as necessary. */
25156 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25159 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25164 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25165 reg = gen_reg_rtx (Pmode);
25167 if (GET_CODE (orig) == CONST)
25171 if (GET_CODE (XEXP (orig, 0)) == PLUS
25172 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25175 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25177 /* Use a different reg for the intermediate value, as
25178 it will be marked UNCHANGING. */
25179 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25180 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25183 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25186 if (GET_CODE (offset) == CONST_INT)
25188 if (SMALL_INT (offset))
25189 return plus_constant (base, INTVAL (offset));
25190 else if (! reload_in_progress && ! reload_completed)
25191 offset = force_reg (Pmode, offset);
25194 rtx mem = force_const_mem (Pmode, orig);
25195 return machopic_legitimize_pic_address (mem, Pmode, reg);
25198 return gen_rtx_PLUS (Pmode, base, offset);
25201 /* Fall back on generic machopic code. */
25202 return machopic_legitimize_pic_address (orig, mode, reg);
25205 /* Output a .machine directive for the Darwin assembler, and call
25206 the generic start_file routine. */
25209 rs6000_darwin_file_start (void)
25211 static const struct
25217 { "ppc64", "ppc64", MASK_64BIT },
25218 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25219 { "power4", "ppc970", 0 },
25220 { "G5", "ppc970", 0 },
25221 { "7450", "ppc7450", 0 },
25222 { "7400", "ppc7400", MASK_ALTIVEC },
25223 { "G4", "ppc7400", 0 },
25224 { "750", "ppc750", 0 },
25225 { "740", "ppc750", 0 },
25226 { "G3", "ppc750", 0 },
25227 { "604e", "ppc604e", 0 },
25228 { "604", "ppc604", 0 },
25229 { "603e", "ppc603", 0 },
25230 { "603", "ppc603", 0 },
25231 { "601", "ppc601", 0 },
25232 { NULL, "ppc", 0 } };
25233 const char *cpu_id = "";
25236 rs6000_file_start ();
25237 darwin_file_start ();
25239 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25241 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25242 cpu_id = rs6000_default_cpu;
25244 if (global_options_set.x_rs6000_cpu_index)
25245 cpu_id = processor_target_table[rs6000_cpu_index].name;
25247 /* Look through the mapping array. Pick the first name that either
25248 matches the argument, has a bit set in IF_SET that is also set
25249 in the target flags, or has a NULL name. */
25252 while (mapping[i].arg != NULL
25253 && strcmp (mapping[i].arg, cpu_id) != 0
25254 && (mapping[i].if_set & target_flags) == 0)
25257 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25260 #endif /* TARGET_MACHO */
25264 rs6000_elf_reloc_rw_mask (void)
25268 else if (DEFAULT_ABI == ABI_AIX)
25274 /* Record an element in the table of global constructors. SYMBOL is
25275 a SYMBOL_REF of the function to be called; PRIORITY is a number
25276 between 0 and MAX_INIT_PRIORITY.
25278 This differs from default_named_section_asm_out_constructor in
25279 that we have special handling for -mrelocatable. */
25282 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25284 const char *section = ".ctors";
25287 if (priority != DEFAULT_INIT_PRIORITY)
25289 sprintf (buf, ".ctors.%.5u",
25290 /* Invert the numbering so the linker puts us in the proper
25291 order; constructors are run from right to left, and the
25292 linker sorts in increasing order. */
25293 MAX_INIT_PRIORITY - priority);
25297 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25298 assemble_align (POINTER_SIZE);
25300 if (TARGET_RELOCATABLE)
25302 fputs ("\t.long (", asm_out_file);
25303 output_addr_const (asm_out_file, symbol);
25304 fputs (")@fixup\n", asm_out_file);
25307 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25311 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25313 const char *section = ".dtors";
25316 if (priority != DEFAULT_INIT_PRIORITY)
25318 sprintf (buf, ".dtors.%.5u",
25319 /* Invert the numbering so the linker puts us in the proper
25320 order; constructors are run from right to left, and the
25321 linker sorts in increasing order. */
25322 MAX_INIT_PRIORITY - priority);
25326 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25327 assemble_align (POINTER_SIZE);
25329 if (TARGET_RELOCATABLE)
25331 fputs ("\t.long (", asm_out_file);
25332 output_addr_const (asm_out_file, symbol);
25333 fputs (")@fixup\n", asm_out_file);
25336 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25340 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25344 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25345 ASM_OUTPUT_LABEL (file, name);
25346 fputs (DOUBLE_INT_ASM_OP, file);
25347 rs6000_output_function_entry (file, name);
25348 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25351 fputs ("\t.size\t", file);
25352 assemble_name (file, name);
25353 fputs (",24\n\t.type\t.", file);
25354 assemble_name (file, name);
25355 fputs (",@function\n", file);
25356 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25358 fputs ("\t.globl\t.", file);
25359 assemble_name (file, name);
25364 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25365 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25366 rs6000_output_function_entry (file, name);
25367 fputs (":\n", file);
25371 if (TARGET_RELOCATABLE
25372 && !TARGET_SECURE_PLT
25373 && (get_pool_size () != 0 || crtl->profile)
25378 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25380 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25381 fprintf (file, "\t.long ");
25382 assemble_name (file, buf);
25384 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25385 assemble_name (file, buf);
25389 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25390 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25392 if (DEFAULT_ABI == ABI_AIX)
25394 const char *desc_name, *orig_name;
25396 orig_name = (*targetm.strip_name_encoding) (name);
25397 desc_name = orig_name;
25398 while (*desc_name == '.')
25401 if (TREE_PUBLIC (decl))
25402 fprintf (file, "\t.globl %s\n", desc_name);
25404 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25405 fprintf (file, "%s:\n", desc_name);
25406 fprintf (file, "\t.long %s\n", orig_name);
25407 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25408 if (DEFAULT_ABI == ABI_AIX)
25409 fputs ("\t.long 0\n", file);
25410 fprintf (file, "\t.previous\n");
25412 ASM_OUTPUT_LABEL (file, name);
25416 rs6000_elf_file_end (void)
25418 #ifdef HAVE_AS_GNU_ATTRIBUTE
25419 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25421 if (rs6000_passes_float)
25422 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25423 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25424 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25426 if (rs6000_passes_vector)
25427 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25428 (TARGET_ALTIVEC_ABI ? 2
25429 : TARGET_SPE_ABI ? 3
25431 if (rs6000_returns_struct)
25432 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25433 aix_struct_return ? 2 : 1);
25436 #ifdef POWERPC_LINUX
25438 file_end_indicate_exec_stack ();
25445 rs6000_xcoff_asm_output_anchor (rtx symbol)
25449 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25450 SYMBOL_REF_BLOCK_OFFSET (symbol));
25451 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25455 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25457 fputs (GLOBAL_ASM_OP, stream);
25458 RS6000_OUTPUT_BASENAME (stream, name);
25459 putc ('\n', stream);
25462 /* A get_unnamed_decl callback, used for read-only sections. PTR
25463 points to the section string variable. */
25466 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25468 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25469 *(const char *const *) directive,
25470 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25473 /* Likewise for read-write sections. */
25476 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25478 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25479 *(const char *const *) directive,
25480 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25483 /* A get_unnamed_section callback, used for switching to toc_section. */
25486 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25488 if (TARGET_MINIMAL_TOC)
25490 /* toc_section is always selected at least once from
25491 rs6000_xcoff_file_start, so this is guaranteed to
25492 always be defined once and only once in each file. */
25493 if (!toc_initialized)
25495 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25496 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25497 toc_initialized = 1;
25499 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25500 (TARGET_32BIT ? "" : ",3"));
25503 fputs ("\t.toc\n", asm_out_file);
25506 /* Implement TARGET_ASM_INIT_SECTIONS. */
25509 rs6000_xcoff_asm_init_sections (void)
25511 read_only_data_section
25512 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25513 &xcoff_read_only_section_name);
25515 private_data_section
25516 = get_unnamed_section (SECTION_WRITE,
25517 rs6000_xcoff_output_readwrite_section_asm_op,
25518 &xcoff_private_data_section_name);
25520 read_only_private_data_section
25521 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25522 &xcoff_private_data_section_name);
25525 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25527 readonly_data_section = read_only_data_section;
25528 exception_section = data_section;
25532 rs6000_xcoff_reloc_rw_mask (void)
25538 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25539 tree decl ATTRIBUTE_UNUSED)
25542 static const char * const suffix[3] = { "PR", "RO", "RW" };
25544 if (flags & SECTION_CODE)
25546 else if (flags & SECTION_WRITE)
25551 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25552 (flags & SECTION_CODE) ? "." : "",
25553 name, suffix[smclass], flags & SECTION_ENTSIZE);
25557 rs6000_xcoff_select_section (tree decl, int reloc,
25558 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25560 if (decl_readonly_section (decl, reloc))
25562 if (TREE_PUBLIC (decl))
25563 return read_only_data_section;
25565 return read_only_private_data_section;
25569 if (TREE_PUBLIC (decl))
25570 return data_section;
25572 return private_data_section;
25577 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25581 /* Use select_section for private and uninitialized data. */
25582 if (!TREE_PUBLIC (decl)
25583 || DECL_COMMON (decl)
25584 || DECL_INITIAL (decl) == NULL_TREE
25585 || DECL_INITIAL (decl) == error_mark_node
25586 || (flag_zero_initialized_in_bss
25587 && initializer_zerop (DECL_INITIAL (decl))))
25590 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25591 name = (*targetm.strip_name_encoding) (name);
25592 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25595 /* Select section for constant in constant pool.
25597 On RS/6000, all constants are in the private read-only data area.
25598 However, if this is being placed in the TOC it must be output as a
25602 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25603 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25605 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25606 return toc_section;
25608 return read_only_private_data_section;
25611 /* Remove any trailing [DS] or the like from the symbol name. */
25613 static const char *
25614 rs6000_xcoff_strip_name_encoding (const char *name)
25619 len = strlen (name);
25620 if (name[len - 1] == ']')
25621 return ggc_alloc_string (name, len - 4);
25626 /* Section attributes. AIX is always PIC. */
25628 static unsigned int
25629 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25631 unsigned int align;
25632 unsigned int flags = default_section_type_flags (decl, name, reloc);
25634 /* Align to at least UNIT size. */
25635 if (flags & SECTION_CODE)
25636 align = MIN_UNITS_PER_WORD;
25638 /* Increase alignment of large objects if not already stricter. */
25639 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25640 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25641 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25643 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25646 /* Output at beginning of assembler file.
25648 Initialize the section names for the RS/6000 at this point.
25650 Specify filename, including full path, to assembler.
25652 We want to go into the TOC section so at least one .toc will be emitted.
25653 Also, in order to output proper .bs/.es pairs, we need at least one static
25654 [RW] section emitted.
25656 Finally, declare mcount when profiling to make the assembler happy. */
25659 rs6000_xcoff_file_start (void)
25661 rs6000_gen_section_name (&xcoff_bss_section_name,
25662 main_input_filename, ".bss_");
25663 rs6000_gen_section_name (&xcoff_private_data_section_name,
25664 main_input_filename, ".rw_");
25665 rs6000_gen_section_name (&xcoff_read_only_section_name,
25666 main_input_filename, ".ro_");
25668 fputs ("\t.file\t", asm_out_file);
25669 output_quoted_string (asm_out_file, main_input_filename);
25670 fputc ('\n', asm_out_file);
25671 if (write_symbols != NO_DEBUG)
25672 switch_to_section (private_data_section);
25673 switch_to_section (text_section);
25675 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25676 rs6000_file_start ();
25679 /* Output at end of assembler file.
25680 On the RS/6000, referencing data should automatically pull in text. */
25683 rs6000_xcoff_file_end (void)
25685 switch_to_section (text_section);
25686 fputs ("_section_.text:\n", asm_out_file);
25687 switch_to_section (data_section);
25688 fputs (TARGET_32BIT
25689 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25692 #endif /* TARGET_XCOFF */
25694 /* Compute a (partial) cost for rtx X. Return true if the complete
25695 cost has been computed, and false if subexpressions should be
25696 scanned. In either case, *TOTAL contains the cost result. */
25699 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25702 enum machine_mode mode = GET_MODE (x);
25706 /* On the RS/6000, if it is valid in the insn, it is free. */
25708 if (((outer_code == SET
25709 || outer_code == PLUS
25710 || outer_code == MINUS)
25711 && (satisfies_constraint_I (x)
25712 || satisfies_constraint_L (x)))
25713 || (outer_code == AND
25714 && (satisfies_constraint_K (x)
25716 ? satisfies_constraint_L (x)
25717 : satisfies_constraint_J (x))
25718 || mask_operand (x, mode)
25720 && mask64_operand (x, DImode))))
25721 || ((outer_code == IOR || outer_code == XOR)
25722 && (satisfies_constraint_K (x)
25724 ? satisfies_constraint_L (x)
25725 : satisfies_constraint_J (x))))
25726 || outer_code == ASHIFT
25727 || outer_code == ASHIFTRT
25728 || outer_code == LSHIFTRT
25729 || outer_code == ROTATE
25730 || outer_code == ROTATERT
25731 || outer_code == ZERO_EXTRACT
25732 || (outer_code == MULT
25733 && satisfies_constraint_I (x))
25734 || ((outer_code == DIV || outer_code == UDIV
25735 || outer_code == MOD || outer_code == UMOD)
25736 && exact_log2 (INTVAL (x)) >= 0)
25737 || (outer_code == COMPARE
25738 && (satisfies_constraint_I (x)
25739 || satisfies_constraint_K (x)))
25740 || ((outer_code == EQ || outer_code == NE)
25741 && (satisfies_constraint_I (x)
25742 || satisfies_constraint_K (x)
25744 ? satisfies_constraint_L (x)
25745 : satisfies_constraint_J (x))))
25746 || (outer_code == GTU
25747 && satisfies_constraint_I (x))
25748 || (outer_code == LTU
25749 && satisfies_constraint_P (x)))
25754 else if ((outer_code == PLUS
25755 && reg_or_add_cint_operand (x, VOIDmode))
25756 || (outer_code == MINUS
25757 && reg_or_sub_cint_operand (x, VOIDmode))
25758 || ((outer_code == SET
25759 || outer_code == IOR
25760 || outer_code == XOR)
25762 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25764 *total = COSTS_N_INSNS (1);
25770 if (mode == DImode && code == CONST_DOUBLE)
25772 if ((outer_code == IOR || outer_code == XOR)
25773 && CONST_DOUBLE_HIGH (x) == 0
25774 && (CONST_DOUBLE_LOW (x)
25775 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25780 else if ((outer_code == AND && and64_2_operand (x, DImode))
25781 || ((outer_code == SET
25782 || outer_code == IOR
25783 || outer_code == XOR)
25784 && CONST_DOUBLE_HIGH (x) == 0))
25786 *total = COSTS_N_INSNS (1);
25796 /* When optimizing for size, MEM should be slightly more expensive
25797 than generating address, e.g., (plus (reg) (const)).
25798 L1 cache latency is about two instructions. */
25799 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25808 if (FLOAT_MODE_P (mode))
25809 *total = rs6000_cost->fp;
25811 *total = COSTS_N_INSNS (1);
25815 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25816 && satisfies_constraint_I (XEXP (x, 1)))
25818 if (INTVAL (XEXP (x, 1)) >= -256
25819 && INTVAL (XEXP (x, 1)) <= 255)
25820 *total = rs6000_cost->mulsi_const9;
25822 *total = rs6000_cost->mulsi_const;
25824 else if (mode == SFmode)
25825 *total = rs6000_cost->fp;
25826 else if (FLOAT_MODE_P (mode))
25827 *total = rs6000_cost->dmul;
25828 else if (mode == DImode)
25829 *total = rs6000_cost->muldi;
25831 *total = rs6000_cost->mulsi;
25835 if (mode == SFmode)
25836 *total = rs6000_cost->fp;
25838 *total = rs6000_cost->dmul;
25843 if (FLOAT_MODE_P (mode))
25845 *total = mode == DFmode ? rs6000_cost->ddiv
25846 : rs6000_cost->sdiv;
25853 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25854 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25856 if (code == DIV || code == MOD)
25858 *total = COSTS_N_INSNS (2);
25861 *total = COSTS_N_INSNS (1);
25865 if (GET_MODE (XEXP (x, 1)) == DImode)
25866 *total = rs6000_cost->divdi;
25868 *total = rs6000_cost->divsi;
25870 /* Add in shift and subtract for MOD. */
25871 if (code == MOD || code == UMOD)
25872 *total += COSTS_N_INSNS (2);
25877 *total = COSTS_N_INSNS (4);
25881 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25885 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25889 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25901 *total = COSTS_N_INSNS (1);
25909 /* Handle mul_highpart. */
25910 if (outer_code == TRUNCATE
25911 && GET_CODE (XEXP (x, 0)) == MULT)
25913 if (mode == DImode)
25914 *total = rs6000_cost->muldi;
25916 *total = rs6000_cost->mulsi;
25919 else if (outer_code == AND)
25922 *total = COSTS_N_INSNS (1);
25927 if (GET_CODE (XEXP (x, 0)) == MEM)
25930 *total = COSTS_N_INSNS (1);
25936 if (!FLOAT_MODE_P (mode))
25938 *total = COSTS_N_INSNS (1);
25944 case UNSIGNED_FLOAT:
25947 case FLOAT_TRUNCATE:
25948 *total = rs6000_cost->fp;
25952 if (mode == DFmode)
25955 *total = rs6000_cost->fp;
25959 switch (XINT (x, 1))
25962 *total = rs6000_cost->fp;
25974 *total = COSTS_N_INSNS (1);
25977 else if (FLOAT_MODE_P (mode)
25978 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25980 *total = rs6000_cost->fp;
25988 /* Carry bit requires mode == Pmode.
25989 NEG or PLUS already counted so only add one. */
25991 && (outer_code == NEG || outer_code == PLUS))
25993 *total = COSTS_N_INSNS (1);
25996 if (outer_code == SET)
25998 if (XEXP (x, 1) == const0_rtx)
26000 if (TARGET_ISEL && !TARGET_MFCRF)
26001 *total = COSTS_N_INSNS (8);
26003 *total = COSTS_N_INSNS (2);
26006 else if (mode == Pmode)
26008 *total = COSTS_N_INSNS (3);
26017 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26019 if (TARGET_ISEL && !TARGET_MFCRF)
26020 *total = COSTS_N_INSNS (8);
26022 *total = COSTS_N_INSNS (2);
26026 if (outer_code == COMPARE)
26040 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26043 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26046 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26049 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26050 "total = %d, speed = %s, x:\n",
26051 ret ? "complete" : "scan inner",
26052 GET_RTX_NAME (code),
26053 GET_RTX_NAME (outer_code),
26055 speed ? "true" : "false");
26062 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26065 rs6000_debug_address_cost (rtx x, bool speed)
26067 int ret = TARGET_ADDRESS_COST (x, speed);
26069 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26070 ret, speed ? "true" : "false");
26077 /* A C expression returning the cost of moving data from a register of class
26078 CLASS1 to one of CLASS2. */
26081 rs6000_register_move_cost (enum machine_mode mode,
26082 reg_class_t from, reg_class_t to)
26086 if (TARGET_DEBUG_COST)
26089 /* Moves from/to GENERAL_REGS. */
26090 if (reg_classes_intersect_p (to, GENERAL_REGS)
26091 || reg_classes_intersect_p (from, GENERAL_REGS))
26093 reg_class_t rclass = from;
26095 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26098 if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
26099 ret = (rs6000_memory_move_cost (mode, rclass, false)
26100 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26102 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26104 else if (rclass == CR_REGS)
26107 /* For those processors that have slow LR/CTR moves, make them more
26108 expensive than memory in order to bias spills to memory .*/
26109 else if ((rs6000_cpu == PROCESSOR_POWER6
26110 || rs6000_cpu == PROCESSOR_POWER7)
26111 && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
26112 ret = 6 * hard_regno_nregs[0][mode];
26115 /* A move will cost one instruction per GPR moved. */
26116 ret = 2 * hard_regno_nregs[0][mode];
26119 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26120 else if (VECTOR_UNIT_VSX_P (mode)
26121 && reg_classes_intersect_p (to, VSX_REGS)
26122 && reg_classes_intersect_p (from, VSX_REGS))
26123 ret = 2 * hard_regno_nregs[32][mode];
26125 /* Moving between two similar registers is just one instruction. */
26126 else if (reg_classes_intersect_p (to, from))
26127 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26129 /* Everything else has to go through GENERAL_REGS. */
26131 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26132 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26134 if (TARGET_DEBUG_COST)
26136 if (dbg_cost_ctrl == 1)
26138 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26139 ret, GET_MODE_NAME (mode), reg_class_names[from],
26140 reg_class_names[to]);
26147 /* A C expressions returning the cost of moving data of MODE from a register to
26151 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26152 bool in ATTRIBUTE_UNUSED)
26156 if (TARGET_DEBUG_COST)
26159 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26160 ret = 4 * hard_regno_nregs[0][mode];
26161 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26162 ret = 4 * hard_regno_nregs[32][mode];
26163 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26164 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26166 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26168 if (TARGET_DEBUG_COST)
26170 if (dbg_cost_ctrl == 1)
26172 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26173 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26180 /* Returns a code for a target-specific builtin that implements
26181 reciprocal of the function, or NULL_TREE if not available. */
26184 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26185 bool sqrt ATTRIBUTE_UNUSED)
26187 if (optimize_insn_for_size_p ())
26193 case VSX_BUILTIN_XVSQRTDP:
26194 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26197 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26199 case VSX_BUILTIN_XVSQRTSP:
26200 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26203 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26212 case BUILT_IN_SQRT:
26213 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26216 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26218 case BUILT_IN_SQRTF:
26219 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26222 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26229 /* Load up a constant. If the mode is a vector mode, splat the value across
26230 all of the vector elements. */
26233 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26237 if (mode == SFmode || mode == DFmode)
26239 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26240 reg = force_reg (mode, d);
26242 else if (mode == V4SFmode)
26244 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26245 rtvec v = gen_rtvec (4, d, d, d, d);
26246 reg = gen_reg_rtx (mode);
26247 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26249 else if (mode == V2DFmode)
26251 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26252 rtvec v = gen_rtvec (2, d, d);
26253 reg = gen_reg_rtx (mode);
26254 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26257 gcc_unreachable ();
26262 /* Generate an FMA instruction. */
26265 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26267 enum machine_mode mode = GET_MODE (target);
26270 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26271 gcc_assert (dst != NULL);
26274 emit_move_insn (target, dst);
26277 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26280 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26282 enum machine_mode mode = GET_MODE (target);
26285 /* Altivec does not support fms directly;
26286 generate in terms of fma in that case. */
26287 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26288 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26291 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26292 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26294 gcc_assert (dst != NULL);
26297 emit_move_insn (target, dst);
26300 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26303 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26305 enum machine_mode mode = GET_MODE (dst);
26308 /* This is a tad more complicated, since the fnma_optab is for
26309 a different expression: fma(-m1, m2, a), which is the same
26310 thing except in the case of signed zeros.
26312 Fortunately we know that if FMA is supported that FNMSUB is
26313 also supported in the ISA. Just expand it directly. */
26315 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26317 r = gen_rtx_NEG (mode, a);
26318 r = gen_rtx_FMA (mode, m1, m2, r);
26319 r = gen_rtx_NEG (mode, r);
26320 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26323 /* Newton-Raphson approximation of floating point divide with just 2 passes
26324 (either single precision floating point, or newer machines with higher
26325 accuracy estimates). Support both scalar and vector divide. Assumes no
26326 trapping math and finite arguments. */
26329 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26331 enum machine_mode mode = GET_MODE (dst);
26332 rtx x0, e0, e1, y1, u0, v0;
26333 enum insn_code code = optab_handler (smul_optab, mode);
26334 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26335 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26337 gcc_assert (code != CODE_FOR_nothing);
26339 /* x0 = 1./d estimate */
26340 x0 = gen_reg_rtx (mode);
26341 emit_insn (gen_rtx_SET (VOIDmode, x0,
26342 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26345 e0 = gen_reg_rtx (mode);
26346 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26348 e1 = gen_reg_rtx (mode);
26349 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26351 y1 = gen_reg_rtx (mode);
26352 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26354 u0 = gen_reg_rtx (mode);
26355 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26357 v0 = gen_reg_rtx (mode);
26358 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26360 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26363 /* Newton-Raphson approximation of floating point divide that has a low
26364 precision estimate. Assumes no trapping math and finite arguments. */
26367 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26369 enum machine_mode mode = GET_MODE (dst);
26370 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26371 enum insn_code code = optab_handler (smul_optab, mode);
26372 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26374 gcc_assert (code != CODE_FOR_nothing);
26376 one = rs6000_load_constant_and_splat (mode, dconst1);
26378 /* x0 = 1./d estimate */
26379 x0 = gen_reg_rtx (mode);
26380 emit_insn (gen_rtx_SET (VOIDmode, x0,
26381 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26384 e0 = gen_reg_rtx (mode);
26385 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26387 y1 = gen_reg_rtx (mode);
26388 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26390 e1 = gen_reg_rtx (mode);
26391 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26393 y2 = gen_reg_rtx (mode);
26394 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26396 e2 = gen_reg_rtx (mode);
26397 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26399 y3 = gen_reg_rtx (mode);
26400 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26402 u0 = gen_reg_rtx (mode);
26403 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26405 v0 = gen_reg_rtx (mode);
26406 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26408 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26411 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26412 add a reg_note saying that this was a division. Support both scalar and
26413 vector divide. Assumes no trapping math and finite arguments. */
26416 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26418 enum machine_mode mode = GET_MODE (dst);
26420 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26421 rs6000_emit_swdiv_high_precision (dst, n, d);
26423 rs6000_emit_swdiv_low_precision (dst, n, d);
26426 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26429 /* Newton-Raphson approximation of single/double-precision floating point
26430 rsqrt. Assumes no trapping math and finite arguments. */
26433 rs6000_emit_swrsqrt (rtx dst, rtx src)
26435 enum machine_mode mode = GET_MODE (src);
26436 rtx x0 = gen_reg_rtx (mode);
26437 rtx y = gen_reg_rtx (mode);
26438 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26439 REAL_VALUE_TYPE dconst3_2;
26442 enum insn_code code = optab_handler (smul_optab, mode);
26443 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26445 gcc_assert (code != CODE_FOR_nothing);
26447 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26448 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26449 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26451 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26453 /* x0 = rsqrt estimate */
26454 emit_insn (gen_rtx_SET (VOIDmode, x0,
26455 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26458 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26459 rs6000_emit_msub (y, src, halfthree, src);
26461 for (i = 0; i < passes; i++)
26463 rtx x1 = gen_reg_rtx (mode);
26464 rtx u = gen_reg_rtx (mode);
26465 rtx v = gen_reg_rtx (mode);
26467 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26468 emit_insn (gen_mul (u, x0, x0));
26469 rs6000_emit_nmsub (v, y, u, halfthree);
26470 emit_insn (gen_mul (x1, x0, v));
26474 emit_move_insn (dst, x0);
26478 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26479 (Power7) targets. DST is the target, and SRC is the argument operand. */
26482 rs6000_emit_popcount (rtx dst, rtx src)
26484 enum machine_mode mode = GET_MODE (dst);
26487 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26488 if (TARGET_POPCNTD)
26490 if (mode == SImode)
26491 emit_insn (gen_popcntdsi2 (dst, src));
26493 emit_insn (gen_popcntddi2 (dst, src));
26497 tmp1 = gen_reg_rtx (mode);
26499 if (mode == SImode)
26501 emit_insn (gen_popcntbsi2 (tmp1, src));
26502 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26504 tmp2 = force_reg (SImode, tmp2);
26505 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26509 emit_insn (gen_popcntbdi2 (tmp1, src));
26510 tmp2 = expand_mult (DImode, tmp1,
26511 GEN_INT ((HOST_WIDE_INT)
26512 0x01010101 << 32 | 0x01010101),
26514 tmp2 = force_reg (DImode, tmp2);
26515 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26520 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26521 target, and SRC is the argument operand. */
26524 rs6000_emit_parity (rtx dst, rtx src)
26526 enum machine_mode mode = GET_MODE (dst);
26529 tmp = gen_reg_rtx (mode);
26531 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26534 if (mode == SImode)
26536 emit_insn (gen_popcntbsi2 (tmp, src));
26537 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26541 emit_insn (gen_popcntbdi2 (tmp, src));
26542 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26547 if (mode == SImode)
26549 /* Is mult+shift >= shift+xor+shift+xor? */
26550 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26552 rtx tmp1, tmp2, tmp3, tmp4;
26554 tmp1 = gen_reg_rtx (SImode);
26555 emit_insn (gen_popcntbsi2 (tmp1, src));
26557 tmp2 = gen_reg_rtx (SImode);
26558 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26559 tmp3 = gen_reg_rtx (SImode);
26560 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26562 tmp4 = gen_reg_rtx (SImode);
26563 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26564 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26567 rs6000_emit_popcount (tmp, src);
26568 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26572 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26573 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26575 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26577 tmp1 = gen_reg_rtx (DImode);
26578 emit_insn (gen_popcntbdi2 (tmp1, src));
26580 tmp2 = gen_reg_rtx (DImode);
26581 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26582 tmp3 = gen_reg_rtx (DImode);
26583 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26585 tmp4 = gen_reg_rtx (DImode);
26586 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26587 tmp5 = gen_reg_rtx (DImode);
26588 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26590 tmp6 = gen_reg_rtx (DImode);
26591 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26592 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26595 rs6000_emit_popcount (tmp, src);
26596 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26600 /* Return an RTX representing where to find the function value of a
26601 function returning MODE. */
26603 rs6000_complex_function_value (enum machine_mode mode)
26605 unsigned int regno;
26607 enum machine_mode inner = GET_MODE_INNER (mode);
26608 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26610 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26611 regno = FP_ARG_RETURN;
26614 regno = GP_ARG_RETURN;
26616 /* 32-bit is OK since it'll go in r3/r4. */
26617 if (TARGET_32BIT && inner_bytes >= 4)
26618 return gen_rtx_REG (mode, regno);
26621 if (inner_bytes >= 8)
26622 return gen_rtx_REG (mode, regno);
26624 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26626 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26627 GEN_INT (inner_bytes));
26628 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26631 /* Target hook for TARGET_FUNCTION_VALUE.
26633 On the SPE, both FPs and vectors are returned in r3.
26635 On RS/6000 an integer value is in r3 and a floating-point value is in
26636 fp1, unless -msoft-float. */
26639 rs6000_function_value (const_tree valtype,
26640 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26641 bool outgoing ATTRIBUTE_UNUSED)
26643 enum machine_mode mode;
26644 unsigned int regno;
26646 /* Special handling for structs in darwin64. */
26648 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26650 CUMULATIVE_ARGS valcum;
26654 valcum.fregno = FP_ARG_MIN_REG;
26655 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26656 /* Do a trial code generation as if this were going to be passed as
26657 an argument; if any part goes in memory, we return NULL. */
26658 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26661 /* Otherwise fall through to standard ABI rules. */
26664 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26666 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26667 return gen_rtx_PARALLEL (DImode,
26669 gen_rtx_EXPR_LIST (VOIDmode,
26670 gen_rtx_REG (SImode, GP_ARG_RETURN),
26672 gen_rtx_EXPR_LIST (VOIDmode,
26673 gen_rtx_REG (SImode,
26674 GP_ARG_RETURN + 1),
26677 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26679 return gen_rtx_PARALLEL (DCmode,
26681 gen_rtx_EXPR_LIST (VOIDmode,
26682 gen_rtx_REG (SImode, GP_ARG_RETURN),
26684 gen_rtx_EXPR_LIST (VOIDmode,
26685 gen_rtx_REG (SImode,
26686 GP_ARG_RETURN + 1),
26688 gen_rtx_EXPR_LIST (VOIDmode,
26689 gen_rtx_REG (SImode,
26690 GP_ARG_RETURN + 2),
26692 gen_rtx_EXPR_LIST (VOIDmode,
26693 gen_rtx_REG (SImode,
26694 GP_ARG_RETURN + 3),
26698 mode = TYPE_MODE (valtype);
26699 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26700 || POINTER_TYPE_P (valtype))
26701 mode = TARGET_32BIT ? SImode : DImode;
26703 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26704 /* _Decimal128 must use an even/odd register pair. */
26705 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26706 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26707 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26708 regno = FP_ARG_RETURN;
26709 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26710 && targetm.calls.split_complex_arg)
26711 return rs6000_complex_function_value (mode);
26712 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26713 return register is used in both cases, and we won't see V2DImode/V2DFmode
26714 for pure altivec, combine the two cases. */
26715 else if (TREE_CODE (valtype) == VECTOR_TYPE
26716 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26717 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
26718 regno = ALTIVEC_ARG_RETURN;
26719 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26720 && (mode == DFmode || mode == DCmode
26721 || mode == TFmode || mode == TCmode))
26722 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26724 regno = GP_ARG_RETURN;
26726 return gen_rtx_REG (mode, regno);
26729 /* Define how to find the value returned by a library function
26730 assuming the value has mode MODE. */
26732 rs6000_libcall_value (enum machine_mode mode)
26734 unsigned int regno;
26736 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26738 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26739 return gen_rtx_PARALLEL (DImode,
26741 gen_rtx_EXPR_LIST (VOIDmode,
26742 gen_rtx_REG (SImode, GP_ARG_RETURN),
26744 gen_rtx_EXPR_LIST (VOIDmode,
26745 gen_rtx_REG (SImode,
26746 GP_ARG_RETURN + 1),
26750 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26751 /* _Decimal128 must use an even/odd register pair. */
26752 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26753 else if (SCALAR_FLOAT_MODE_P (mode)
26754 && TARGET_HARD_FLOAT && TARGET_FPRS
26755 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26756 regno = FP_ARG_RETURN;
26757 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26758 return register is used in both cases, and we won't see V2DImode/V2DFmode
26759 for pure altivec, combine the two cases. */
26760 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
26761 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26762 regno = ALTIVEC_ARG_RETURN;
26763 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26764 return rs6000_complex_function_value (mode);
26765 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26766 && (mode == DFmode || mode == DCmode
26767 || mode == TFmode || mode == TCmode))
26768 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26770 regno = GP_ARG_RETURN;
26772 return gen_rtx_REG (mode, regno);
26776 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26777 Frame pointer elimination is automatically handled.
26779 For the RS/6000, if frame pointer elimination is being done, we would like
26780 to convert ap into fp, not sp.
26782 We need r30 if -mminimal-toc was specified, and there are constant pool
26786 rs6000_can_eliminate (const int from, const int to)
26788 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26789 ? ! frame_pointer_needed
26790 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26791 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26795 /* Define the offset between two registers, FROM to be eliminated and its
26796 replacement TO, at the start of a routine. */
26798 rs6000_initial_elimination_offset (int from, int to)
26800 rs6000_stack_t *info = rs6000_stack_info ();
26801 HOST_WIDE_INT offset;
26803 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26804 offset = info->push_p ? 0 : -info->total_size;
26805 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26807 offset = info->push_p ? 0 : -info->total_size;
26808 if (FRAME_GROWS_DOWNWARD)
26809 offset += info->fixed_size + info->vars_size + info->parm_size;
26811 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26812 offset = FRAME_GROWS_DOWNWARD
26813 ? info->fixed_size + info->vars_size + info->parm_size
26815 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26816 offset = info->total_size;
26817 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26818 offset = info->push_p ? info->total_size : 0;
26819 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26822 gcc_unreachable ();
26828 rs6000_dwarf_register_span (rtx reg)
26832 unsigned regno = REGNO (reg);
26833 enum machine_mode mode = GET_MODE (reg);
26837 && (SPE_VECTOR_MODE (GET_MODE (reg))
26838 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26839 && mode != SFmode && mode != SDmode && mode != SCmode)))
26844 regno = REGNO (reg);
26846 /* The duality of the SPE register size wreaks all kinds of havoc.
26847 This is a way of distinguishing r0 in 32-bits from r0 in
26849 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26850 gcc_assert (words <= 4);
26851 for (i = 0; i < words; i++, regno++)
26853 if (BYTES_BIG_ENDIAN)
26855 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26856 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26860 parts[2 * i] = gen_rtx_REG (SImode, regno);
26861 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26865 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26868 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26871 rs6000_init_dwarf_reg_sizes_extra (tree address)
26876 enum machine_mode mode = TYPE_MODE (char_type_node);
26877 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26878 rtx mem = gen_rtx_MEM (BLKmode, addr);
26879 rtx value = gen_int_mode (4, mode);
26881 for (i = 1201; i < 1232; i++)
26883 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26884 HOST_WIDE_INT offset
26885 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26887 emit_move_insn (adjust_address (mem, mode, offset), value);
26892 /* Map internal gcc register numbers to DWARF2 register numbers. */
26895 rs6000_dbx_register_number (unsigned int regno)
26897 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26899 if (regno == MQ_REGNO)
26901 if (regno == LR_REGNO)
26903 if (regno == CTR_REGNO)
26905 if (CR_REGNO_P (regno))
26906 return regno - CR0_REGNO + 86;
26907 if (regno == CA_REGNO)
26908 return 101; /* XER */
26909 if (ALTIVEC_REGNO_P (regno))
26910 return regno - FIRST_ALTIVEC_REGNO + 1124;
26911 if (regno == VRSAVE_REGNO)
26913 if (regno == VSCR_REGNO)
26915 if (regno == SPE_ACC_REGNO)
26917 if (regno == SPEFSCR_REGNO)
26919 /* SPE high reg number. We get these values of regno from
26920 rs6000_dwarf_register_span. */
26921 gcc_assert (regno >= 1200 && regno < 1232);
26925 /* target hook eh_return_filter_mode */
26926 static enum machine_mode
26927 rs6000_eh_return_filter_mode (void)
26929 return TARGET_32BIT ? SImode : word_mode;
26932 /* Target hook for scalar_mode_supported_p. */
26934 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26936 if (DECIMAL_FLOAT_MODE_P (mode))
26937 return default_decimal_float_supported_p ();
26939 return default_scalar_mode_supported_p (mode);
26942 /* Target hook for vector_mode_supported_p. */
26944 rs6000_vector_mode_supported_p (enum machine_mode mode)
26947 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26950 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26953 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26960 /* Target hook for invalid_arg_for_unprototyped_fn. */
26961 static const char *
26962 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26964 return (!rs6000_darwin64_abi
26966 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26967 && (funcdecl == NULL_TREE
26968 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26969 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26970 ? N_("AltiVec argument passed to unprototyped function")
26974 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26975 setup by using __stack_chk_fail_local hidden function instead of
26976 calling __stack_chk_fail directly. Otherwise it is better to call
26977 __stack_chk_fail directly. */
26979 static tree ATTRIBUTE_UNUSED
26980 rs6000_stack_protect_fail (void)
26982 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26983 ? default_hidden_stack_protect_fail ()
26984 : default_external_stack_protect_fail ();
26988 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26989 int num_operands ATTRIBUTE_UNUSED)
26991 if (rs6000_warn_cell_microcode)
26994 int insn_code_number = recog_memoized (insn);
26995 location_t location = locator_location (INSN_LOCATOR (insn));
26997 /* Punt on insns we cannot recognize. */
26998 if (insn_code_number < 0)
27001 temp = get_insn_template (insn_code_number, insn);
27003 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27004 warning_at (location, OPT_mwarn_cell_microcode,
27005 "emitting microcode insn %s\t[%s] #%d",
27006 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27007 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27008 warning_at (location, OPT_mwarn_cell_microcode,
27009 "emitting conditional microcode insn %s\t[%s] #%d",
27010 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27015 /* Mask options that we want to support inside of attribute((target)) and
27016 #pragma GCC target operations. Note, we do not include things like
27017 64/32-bit, endianess, hard/soft floating point, etc. that would have
27018 different calling sequences. */
27020 struct rs6000_opt_mask {
27021 const char *name; /* option name */
27022 int mask; /* mask to set */
27023 bool invert; /* invert sense of mask */
27024 bool valid_target; /* option is a target option */
27027 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27029 { "altivec", MASK_ALTIVEC, false, true },
27030 { "cmpb", MASK_CMPB, false, true },
27031 { "dlmzb", MASK_DLMZB, false, true },
27032 { "fprnd", MASK_FPRND, false, true },
27033 { "hard-dfp", MASK_DFP, false, true },
27034 { "isel", MASK_ISEL, false, true },
27035 { "mfcrf", MASK_MFCRF, false, true },
27036 { "mfpgpr", MASK_MFPGPR, false, true },
27037 { "mulhw", MASK_MULHW, false, true },
27038 { "multiple", MASK_MULTIPLE, false, true },
27039 { "update", MASK_NO_UPDATE, true , true },
27040 { "popcntb", MASK_POPCNTB, false, true },
27041 { "popcntd", MASK_POPCNTD, false, true },
27042 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27043 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27044 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27045 { "string", MASK_STRING, false, true },
27046 { "vsx", MASK_VSX, false, true },
27049 { "aix64", MASK_64BIT, false, false },
27050 { "aix32", MASK_64BIT, true, false },
27052 { "64", MASK_64BIT, false, false },
27053 { "32", MASK_64BIT, true, false },
27057 { "eabi", MASK_EABI, false, false },
27059 #ifdef MASK_LITTLE_ENDIAN
27060 { "little", MASK_LITTLE_ENDIAN, false, false },
27061 { "big", MASK_LITTLE_ENDIAN, true, false },
27063 #ifdef MASK_RELOCATABLE
27064 { "relocatable", MASK_RELOCATABLE, false, false },
27066 #ifdef MASK_STRICT_ALIGN
27067 { "strict-align", MASK_STRICT_ALIGN, false, false },
27069 { "power", MASK_POWER, false, false },
27070 { "power2", MASK_POWER2, false, false },
27071 { "powerpc", MASK_POWERPC, false, false },
27072 { "soft-float", MASK_SOFT_FLOAT, false, false },
27073 { "string", MASK_STRING, false, false },
27076 /* Option variables that we want to support inside attribute((target)) and
27077 #pragma GCC target operations. */
27079 struct rs6000_opt_var {
27080 const char *name; /* option name */
27081 size_t global_offset; /* offset of the option in global_options. */
27082 size_t target_offset; /* offset of the option in target optiosn. */
27085 static struct rs6000_opt_var const rs6000_opt_vars[] =
27088 offsetof (struct gcc_options, x_TARGET_FRIZ),
27089 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27090 { "avoid-indexed-addresses",
27091 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27092 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27094 offsetof (struct gcc_options, x_rs6000_paired_float),
27095 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27097 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27098 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27101 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27102 parsing. Return true if there were no errors. */
27105 rs6000_inner_target_options (tree args, bool attr_p)
27109 if (args == NULL_TREE)
27112 else if (TREE_CODE (args) == STRING_CST)
27114 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27117 while ((q = strtok (p, ",")) != NULL)
27119 bool error_p = false;
27120 bool not_valid_p = false;
27121 const char *cpu_opt = NULL;
27124 if (strncmp (q, "cpu=", 4) == 0)
27126 int cpu_index = rs6000_cpu_name_lookup (q+4);
27127 if (cpu_index >= 0)
27128 rs6000_cpu_index = cpu_index;
27135 else if (strncmp (q, "tune=", 5) == 0)
27137 int tune_index = rs6000_cpu_name_lookup (q+5);
27138 if (tune_index >= 0)
27139 rs6000_tune_index = tune_index;
27149 bool invert = false;
27153 if (strncmp (r, "no-", 3) == 0)
27159 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27160 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27162 int mask = rs6000_opt_masks[i].mask;
27164 if (!rs6000_opt_masks[i].valid_target)
27165 not_valid_p = true;
27169 target_flags_explicit |= mask;
27171 if (rs6000_opt_masks[i].invert)
27175 target_flags &= ~mask;
27177 target_flags |= mask;
27182 if (error_p && !not_valid_p)
27184 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27185 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27187 size_t j = rs6000_opt_vars[i].global_offset;
27188 ((int *) &global_options)[j] = !invert;
27197 const char *eprefix, *esuffix;
27202 eprefix = "__attribute__((__target__(";
27207 eprefix = "#pragma GCC target ";
27212 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27214 else if (not_valid_p)
27215 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27217 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27222 else if (TREE_CODE (args) == TREE_LIST)
27226 tree value = TREE_VALUE (args);
27229 bool ret2 = rs6000_inner_target_options (value, attr_p);
27233 args = TREE_CHAIN (args);
27235 while (args != NULL_TREE);
27239 gcc_unreachable ();
27244 /* Print out the target options as a list for -mdebug=target. */
27247 rs6000_debug_target_options (tree args, const char *prefix)
27249 if (args == NULL_TREE)
27250 fprintf (stderr, "%s<NULL>", prefix);
27252 else if (TREE_CODE (args) == STRING_CST)
27254 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27257 while ((q = strtok (p, ",")) != NULL)
27260 fprintf (stderr, "%s\"%s\"", prefix, q);
27265 else if (TREE_CODE (args) == TREE_LIST)
27269 tree value = TREE_VALUE (args);
27272 rs6000_debug_target_options (value, prefix);
27275 args = TREE_CHAIN (args);
27277 while (args != NULL_TREE);
27281 gcc_unreachable ();
27287 /* Hook to validate attribute((target("..."))). */
27290 rs6000_valid_attribute_p (tree fndecl,
27291 tree ARG_UNUSED (name),
27295 struct cl_target_option cur_target;
27297 tree old_optimize = build_optimization_node ();
27298 tree new_target, new_optimize;
27299 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27301 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27303 if (TARGET_DEBUG_TARGET)
27305 tree tname = DECL_NAME (fndecl);
27306 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27308 fprintf (stderr, "function: %.*s\n",
27309 (int) IDENTIFIER_LENGTH (tname),
27310 IDENTIFIER_POINTER (tname));
27312 fprintf (stderr, "function: unknown\n");
27314 fprintf (stderr, "args:");
27315 rs6000_debug_target_options (args, " ");
27316 fprintf (stderr, "\n");
27319 fprintf (stderr, "flags: 0x%x\n", flags);
27321 fprintf (stderr, "--------------------\n");
27324 old_optimize = build_optimization_node ();
27325 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27327 /* If the function changed the optimization levels as well as setting target
27328 options, start with the optimizations specified. */
27329 if (func_optimize && func_optimize != old_optimize)
27330 cl_optimization_restore (&global_options,
27331 TREE_OPTIMIZATION (func_optimize));
27333 /* The target attributes may also change some optimization flags, so update
27334 the optimization options if necessary. */
27335 cl_target_option_save (&cur_target, &global_options);
27336 rs6000_cpu_index = rs6000_tune_index = -1;
27337 ret = rs6000_inner_target_options (args, true);
27339 /* Set up any additional state. */
27342 ret = rs6000_option_override_internal (false);
27343 new_target = build_target_option_node ();
27348 new_optimize = build_optimization_node ();
27355 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27357 if (old_optimize != new_optimize)
27358 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27361 cl_target_option_restore (&global_options, &cur_target);
27363 if (old_optimize != new_optimize)
27364 cl_optimization_restore (&global_options,
27365 TREE_OPTIMIZATION (old_optimize));
27371 /* Hook to validate the current #pragma GCC target and set the state, and
27372 update the macros based on what was changed. If ARGS is NULL, then
27373 POP_TARGET is used to reset the options. */
27376 rs6000_pragma_target_parse (tree args, tree pop_target)
27381 if (TARGET_DEBUG_TARGET)
27383 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27384 fprintf (stderr, "args:");
27385 rs6000_debug_target_options (args, " ");
27386 fprintf (stderr, "\n");
27390 fprintf (stderr, "pop_target:\n");
27391 debug_tree (pop_target);
27394 fprintf (stderr, "pop_target: <NULL>\n");
27396 fprintf (stderr, "--------------------\n");
27402 cur_tree = ((pop_target)
27404 : target_option_default_node);
27405 cl_target_option_restore (&global_options,
27406 TREE_TARGET_OPTION (cur_tree));
27410 rs6000_cpu_index = rs6000_tune_index = -1;
27411 ret = rs6000_inner_target_options (args, false);
27412 cur_tree = build_target_option_node ();
27419 target_option_current_node = cur_tree;
27425 /* Remember the last target of rs6000_set_current_function. */
27426 static GTY(()) tree rs6000_previous_fndecl;
27428 /* Establish appropriate back-end context for processing the function
27429 FNDECL. The argument might be NULL to indicate processing at top
27430 level, outside of any function scope. */
27432 rs6000_set_current_function (tree fndecl)
27434 tree old_tree = (rs6000_previous_fndecl
27435 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27438 tree new_tree = (fndecl
27439 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27442 if (TARGET_DEBUG_TARGET)
27444 bool print_final = false;
27445 fprintf (stderr, "\n==================== rs6000_set_current_function");
27448 fprintf (stderr, ", fndecl %s (%p)",
27449 (DECL_NAME (fndecl)
27450 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27451 : "<unknown>"), (void *)fndecl);
27453 if (rs6000_previous_fndecl)
27454 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27456 fprintf (stderr, "\n");
27459 fprintf (stderr, "\nnew fndecl target specific options:\n");
27460 debug_tree (new_tree);
27461 print_final = true;
27466 fprintf (stderr, "\nold fndecl target specific options:\n");
27467 debug_tree (old_tree);
27468 print_final = true;
27472 fprintf (stderr, "--------------------\n");
27475 /* Only change the context if the function changes. This hook is called
27476 several times in the course of compiling a function, and we don't want to
27477 slow things down too much or call target_reinit when it isn't safe. */
27478 if (fndecl && fndecl != rs6000_previous_fndecl)
27480 rs6000_previous_fndecl = fndecl;
27481 if (old_tree == new_tree)
27486 cl_target_option_restore (&global_options,
27487 TREE_TARGET_OPTION (new_tree));
27493 struct cl_target_option *def
27494 = TREE_TARGET_OPTION (target_option_current_node);
27496 cl_target_option_restore (&global_options, def);
27503 /* Save the current options */
27506 rs6000_function_specific_save (struct cl_target_option *ptr)
27508 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27511 /* Restore the current options */
27514 rs6000_function_specific_restore (struct cl_target_option *ptr)
27516 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27517 (void) rs6000_option_override_internal (false);
27520 /* Print the current options */
27523 rs6000_function_specific_print (FILE *file, int indent,
27524 struct cl_target_option *ptr)
27527 int flags = ptr->x_target_flags;
27529 /* Print the various mask options. */
27530 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27531 if ((flags & rs6000_opt_masks[i].mask) != 0)
27533 flags &= ~ rs6000_opt_masks[i].mask;
27534 fprintf (file, "%*s-m%s%s\n", indent, "",
27535 rs6000_opt_masks[i].invert ? "no-" : "",
27536 rs6000_opt_masks[i].name);
27539 /* Print the various options that are variables. */
27540 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27542 size_t j = rs6000_opt_vars[i].target_offset;
27543 if (((signed char *) ptr)[j])
27544 fprintf (file, "%*s-m%s\n", indent, "",
27545 rs6000_opt_vars[i].name);
27550 /* Hook to determine if one function can safely inline another. */
27553 rs6000_can_inline_p (tree caller, tree callee)
27556 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27557 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27559 /* If callee has no option attributes, then it is ok to inline. */
27563 /* If caller has no option attributes, but callee does then it is not ok to
27565 else if (!caller_tree)
27570 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27571 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27573 /* Callee's options should a subset of the caller's, i.e. a vsx function
27574 can inline an altivec function but a non-vsx function can't inline a
27576 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27577 == callee_opts->x_target_flags)
27581 if (TARGET_DEBUG_TARGET)
27582 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27583 (DECL_NAME (caller)
27584 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27586 (DECL_NAME (callee)
27587 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27589 (ret ? "can" : "cannot"));
27594 /* Allocate a stack temp and fixup the address so it meets the particular
27595 memory requirements (either offetable or REG+REG addressing). */
27598 rs6000_allocate_stack_temp (enum machine_mode mode,
27599 bool offsettable_p,
27602 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27603 rtx addr = XEXP (stack, 0);
27604 int strict_p = (reload_in_progress || reload_completed);
27606 if (!legitimate_indirect_address_p (addr, strict_p))
27609 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27610 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27612 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27613 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27619 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27620 to such a form to deal with memory reference instructions like STFIWX that
27621 only take reg+reg addressing. */
27624 rs6000_address_for_fpconvert (rtx x)
27626 int strict_p = (reload_in_progress || reload_completed);
27629 gcc_assert (MEM_P (x));
27630 addr = XEXP (x, 0);
27631 if (! legitimate_indirect_address_p (addr, strict_p)
27632 && ! legitimate_indexed_address_p (addr, strict_p))
27634 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27636 rtx reg = XEXP (addr, 0);
27637 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27638 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27639 gcc_assert (REG_P (reg));
27640 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27643 else if (GET_CODE (addr) == PRE_MODIFY)
27645 rtx reg = XEXP (addr, 0);
27646 rtx expr = XEXP (addr, 1);
27647 gcc_assert (REG_P (reg));
27648 gcc_assert (GET_CODE (expr) == PLUS);
27649 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27653 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27659 /* Given a memory reference, if it is not in the form for altivec memory
27660 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27661 convert to the altivec format. */
27664 rs6000_address_for_altivec (rtx x)
27666 gcc_assert (MEM_P (x));
27667 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27669 rtx addr = XEXP (x, 0);
27670 int strict_p = (reload_in_progress || reload_completed);
27672 if (!legitimate_indexed_address_p (addr, strict_p)
27673 && !legitimate_indirect_address_p (addr, strict_p))
27674 addr = copy_to_mode_reg (Pmode, addr);
27676 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
27677 x = change_address (x, GET_MODE (x), addr);
27683 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27685 On the RS/6000, all integer constants are acceptable, most won't be valid
27686 for particular insns, though. Only easy FP constants are acceptable. */
27689 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
27691 if (rs6000_tls_referenced_p (x))
27694 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
27695 || GET_MODE (x) == VOIDmode
27696 || (TARGET_POWERPC64 && mode == DImode)
27697 || easy_fp_constant (x, mode)
27698 || easy_vector_constant (x, mode));
27702 /* A function pointer under AIX is a pointer to a data area whose first word
27703 contains the actual address of the function, whose second word contains a
27704 pointer to its TOC, and whose third word contains a value to place in the
27705 static chain register (r11). Note that if we load the static chain, our
27706 "trampoline" need not have any executable code. */
27709 rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
27715 rtx stack_toc_offset;
27717 rtx func_toc_offset;
27719 rtx func_sc_offset;
27722 rtx (*call_func) (rtx, rtx, rtx, rtx);
27723 rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx);
27725 stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
27726 toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
27728 /* Load up address of the actual function. */
27729 func_desc = force_reg (Pmode, func_desc);
27730 func_addr = gen_reg_rtx (Pmode);
27731 emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
27736 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT);
27737 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT);
27738 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT);
27739 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27741 call_func = gen_call_indirect_aix32bit;
27742 call_value_func = gen_call_value_indirect_aix32bit;
27746 call_func = gen_call_indirect_aix32bit_nor11;
27747 call_value_func = gen_call_value_indirect_aix32bit_nor11;
27752 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT);
27753 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT);
27754 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT);
27755 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27757 call_func = gen_call_indirect_aix64bit;
27758 call_value_func = gen_call_value_indirect_aix64bit;
27762 call_func = gen_call_indirect_aix64bit_nor11;
27763 call_value_func = gen_call_value_indirect_aix64bit_nor11;
27767 /* Reserved spot to store the TOC. */
27768 stack_toc_mem = gen_frame_mem (Pmode,
27769 gen_rtx_PLUS (Pmode,
27771 stack_toc_offset));
27774 gcc_assert (cfun->machine);
27776 /* Can we optimize saving the TOC in the prologue or do we need to do it at
27778 if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca
27779 && !cfun->calls_setjmp && !cfun->has_nonlocal_label
27780 && !cfun->can_throw_non_call_exceptions
27781 && ((flags_from_decl_or_type (cfun->decl) & ECF_NOTHROW) == ECF_NOTHROW))
27782 cfun->machine->save_toc_in_prologue = true;
27786 MEM_VOLATILE_P (stack_toc_mem) = 1;
27787 emit_move_insn (stack_toc_mem, toc_reg);
27790 /* Calculate the address to load the TOC of the called function. We don't
27791 actually load this until the split after reload. */
27792 func_toc_mem = gen_rtx_MEM (Pmode,
27793 gen_rtx_PLUS (Pmode,
27797 /* If we have a static chain, load it up. */
27798 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27800 func_sc_mem = gen_rtx_MEM (Pmode,
27801 gen_rtx_PLUS (Pmode,
27805 sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
27806 emit_move_insn (sc_reg, func_sc_mem);
27809 /* Create the call. */
27811 insn = call_value_func (value, func_addr, flag, func_toc_mem,
27814 insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
27816 emit_call_insn (insn);
27820 /* Return whether we need to always update the saved TOC pointer when we update
27821 the stack pointer. */
27824 rs6000_save_toc_in_prologue_p (void)
27826 return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
27829 #include "gt-rs6000.h"