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 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
134 varargs save area. */
135 HOST_WIDE_INT varargs_save_offset;
136 /* Temporary stack slot to use for SDmode copies. This slot is
137 64-bits wide and is allocated early enough so that the offset
138 does not overflow the 16-bit load/store offset field. */
139 rtx sdmode_stack_slot;
142 /* Support targetm.vectorize.builtin_mask_for_load. */
143 static GTY(()) tree altivec_builtin_mask_for_load;
145 /* Set to nonzero once AIX common-mode calls have been defined. */
146 static GTY(()) int common_mode_defined;
148 /* Label number of label created for -mrelocatable, to call to so we can
149 get the address of the GOT section */
150 static int rs6000_pic_labelno;
153 /* Counter for labels which are to be placed in .fixup. */
154 int fixuplabelno = 0;
157 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
160 /* Specify the machine mode that pointers have. After generation of rtl, the
161 compiler makes no further distinction between pointers and any other objects
162 of this machine mode. The type is unsigned since not all things that
163 include rs6000.h also include machmode.h. */
164 unsigned rs6000_pmode;
166 /* Width in bits of a pointer. */
167 unsigned rs6000_pointer_size;
169 #ifdef HAVE_AS_GNU_ATTRIBUTE
170 /* Flag whether floating point values have been passed/returned. */
171 static bool rs6000_passes_float;
172 /* Flag whether vector values have been passed/returned. */
173 static bool rs6000_passes_vector;
174 /* Flag whether small (<= 8 byte) structures have been returned. */
175 static bool rs6000_returns_struct;
178 /* Value is TRUE if register/mode pair is acceptable. */
179 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
181 /* Maximum number of registers needed for a given register class and mode. */
182 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
184 /* How many registers are needed for a given register and mode. */
185 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
187 /* Map register number to register class. */
188 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
190 /* Reload functions based on the type and the vector unit. */
191 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
193 static int dbg_cost_ctrl;
195 /* Built in types. */
196 tree rs6000_builtin_types[RS6000_BTI_MAX];
197 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
199 /* Flag to say the TOC is initialized */
201 char toc_label_name[10];
203 /* Cached value of rs6000_variable_issue. This is cached in
204 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
205 static short cached_can_issue_more;
207 static GTY(()) section *read_only_data_section;
208 static GTY(()) section *private_data_section;
209 static GTY(()) section *read_only_private_data_section;
210 static GTY(()) section *sdata2_section;
211 static GTY(()) section *toc_section;
213 struct builtin_description
215 /* mask is not const because we're going to alter it below. This
216 nonsense will go away when we rewrite the -march infrastructure
217 to give us more target flag bits. */
219 const enum insn_code icode;
220 const char *const name;
221 const enum rs6000_builtins code;
224 /* Describe the vector unit used for modes. */
225 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
226 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
228 /* Register classes for various constraints that are based on the target
230 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
232 /* Describe the alignment of a vector. */
233 int rs6000_vector_align[NUM_MACHINE_MODES];
235 /* Map selected modes to types for builtins. */
236 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
238 /* What modes to automatically generate reciprocal divide estimate (fre) and
239 reciprocal sqrt (frsqrte) for. */
240 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
242 /* Masks to determine which reciprocal esitmate instructions to generate
244 enum rs6000_recip_mask {
245 RECIP_SF_DIV = 0x001, /* Use divide estimate */
246 RECIP_DF_DIV = 0x002,
247 RECIP_V4SF_DIV = 0x004,
248 RECIP_V2DF_DIV = 0x008,
250 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
251 RECIP_DF_RSQRT = 0x020,
252 RECIP_V4SF_RSQRT = 0x040,
253 RECIP_V2DF_RSQRT = 0x080,
255 /* Various combination of flags for -mrecip=xxx. */
257 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
258 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
259 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
261 RECIP_HIGH_PRECISION = RECIP_ALL,
263 /* On low precision machines like the power5, don't enable double precision
264 reciprocal square root estimate, since it isn't accurate enough. */
265 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
268 /* -mrecip options. */
271 const char *string; /* option name */
272 unsigned int mask; /* mask bits to set */
273 } recip_options[] = {
274 { "all", RECIP_ALL },
275 { "none", RECIP_NONE },
276 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
278 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
279 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
280 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
281 | RECIP_V2DF_RSQRT) },
282 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
283 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
286 /* 2 argument gen function typedef. */
287 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
290 /* Target cpu costs. */
292 struct processor_costs {
293 const int mulsi; /* cost of SImode multiplication. */
294 const int mulsi_const; /* cost of SImode multiplication by constant. */
295 const int mulsi_const9; /* cost of SImode mult by short constant. */
296 const int muldi; /* cost of DImode multiplication. */
297 const int divsi; /* cost of SImode division. */
298 const int divdi; /* cost of DImode division. */
299 const int fp; /* cost of simple SFmode and DFmode insns. */
300 const int dmul; /* cost of DFmode multiplication (and fmadd). */
301 const int sdiv; /* cost of SFmode division (fdivs). */
302 const int ddiv; /* cost of DFmode division (fdiv). */
303 const int cache_line_size; /* cache line size in bytes. */
304 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
305 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
306 const int simultaneous_prefetches; /* number of parallel prefetch
310 const struct processor_costs *rs6000_cost;
312 /* Processor costs (relative to an add) */
314 /* Instruction size costs on 32bit processors. */
316 struct processor_costs size32_cost = {
317 COSTS_N_INSNS (1), /* mulsi */
318 COSTS_N_INSNS (1), /* mulsi_const */
319 COSTS_N_INSNS (1), /* mulsi_const9 */
320 COSTS_N_INSNS (1), /* muldi */
321 COSTS_N_INSNS (1), /* divsi */
322 COSTS_N_INSNS (1), /* divdi */
323 COSTS_N_INSNS (1), /* fp */
324 COSTS_N_INSNS (1), /* dmul */
325 COSTS_N_INSNS (1), /* sdiv */
326 COSTS_N_INSNS (1), /* ddiv */
333 /* Instruction size costs on 64bit processors. */
335 struct processor_costs size64_cost = {
336 COSTS_N_INSNS (1), /* mulsi */
337 COSTS_N_INSNS (1), /* mulsi_const */
338 COSTS_N_INSNS (1), /* mulsi_const9 */
339 COSTS_N_INSNS (1), /* muldi */
340 COSTS_N_INSNS (1), /* divsi */
341 COSTS_N_INSNS (1), /* divdi */
342 COSTS_N_INSNS (1), /* fp */
343 COSTS_N_INSNS (1), /* dmul */
344 COSTS_N_INSNS (1), /* sdiv */
345 COSTS_N_INSNS (1), /* ddiv */
352 /* Instruction costs on RIOS1 processors. */
354 struct processor_costs rios1_cost = {
355 COSTS_N_INSNS (5), /* mulsi */
356 COSTS_N_INSNS (4), /* mulsi_const */
357 COSTS_N_INSNS (3), /* mulsi_const9 */
358 COSTS_N_INSNS (5), /* muldi */
359 COSTS_N_INSNS (19), /* divsi */
360 COSTS_N_INSNS (19), /* divdi */
361 COSTS_N_INSNS (2), /* fp */
362 COSTS_N_INSNS (2), /* dmul */
363 COSTS_N_INSNS (19), /* sdiv */
364 COSTS_N_INSNS (19), /* ddiv */
365 128, /* cache line size */
371 /* Instruction costs on RIOS2 processors. */
373 struct processor_costs rios2_cost = {
374 COSTS_N_INSNS (2), /* mulsi */
375 COSTS_N_INSNS (2), /* mulsi_const */
376 COSTS_N_INSNS (2), /* mulsi_const9 */
377 COSTS_N_INSNS (2), /* muldi */
378 COSTS_N_INSNS (13), /* divsi */
379 COSTS_N_INSNS (13), /* divdi */
380 COSTS_N_INSNS (2), /* fp */
381 COSTS_N_INSNS (2), /* dmul */
382 COSTS_N_INSNS (17), /* sdiv */
383 COSTS_N_INSNS (17), /* ddiv */
384 256, /* cache line size */
390 /* Instruction costs on RS64A processors. */
392 struct processor_costs rs64a_cost = {
393 COSTS_N_INSNS (20), /* mulsi */
394 COSTS_N_INSNS (12), /* mulsi_const */
395 COSTS_N_INSNS (8), /* mulsi_const9 */
396 COSTS_N_INSNS (34), /* muldi */
397 COSTS_N_INSNS (65), /* divsi */
398 COSTS_N_INSNS (67), /* divdi */
399 COSTS_N_INSNS (4), /* fp */
400 COSTS_N_INSNS (4), /* dmul */
401 COSTS_N_INSNS (31), /* sdiv */
402 COSTS_N_INSNS (31), /* ddiv */
403 128, /* cache line size */
409 /* Instruction costs on MPCCORE processors. */
411 struct processor_costs mpccore_cost = {
412 COSTS_N_INSNS (2), /* mulsi */
413 COSTS_N_INSNS (2), /* mulsi_const */
414 COSTS_N_INSNS (2), /* mulsi_const9 */
415 COSTS_N_INSNS (2), /* muldi */
416 COSTS_N_INSNS (6), /* divsi */
417 COSTS_N_INSNS (6), /* divdi */
418 COSTS_N_INSNS (4), /* fp */
419 COSTS_N_INSNS (5), /* dmul */
420 COSTS_N_INSNS (10), /* sdiv */
421 COSTS_N_INSNS (17), /* ddiv */
422 32, /* cache line size */
428 /* Instruction costs on PPC403 processors. */
430 struct processor_costs ppc403_cost = {
431 COSTS_N_INSNS (4), /* mulsi */
432 COSTS_N_INSNS (4), /* mulsi_const */
433 COSTS_N_INSNS (4), /* mulsi_const9 */
434 COSTS_N_INSNS (4), /* muldi */
435 COSTS_N_INSNS (33), /* divsi */
436 COSTS_N_INSNS (33), /* divdi */
437 COSTS_N_INSNS (11), /* fp */
438 COSTS_N_INSNS (11), /* dmul */
439 COSTS_N_INSNS (11), /* sdiv */
440 COSTS_N_INSNS (11), /* ddiv */
441 32, /* cache line size */
447 /* Instruction costs on PPC405 processors. */
449 struct processor_costs ppc405_cost = {
450 COSTS_N_INSNS (5), /* mulsi */
451 COSTS_N_INSNS (4), /* mulsi_const */
452 COSTS_N_INSNS (3), /* mulsi_const9 */
453 COSTS_N_INSNS (5), /* muldi */
454 COSTS_N_INSNS (35), /* divsi */
455 COSTS_N_INSNS (35), /* divdi */
456 COSTS_N_INSNS (11), /* fp */
457 COSTS_N_INSNS (11), /* dmul */
458 COSTS_N_INSNS (11), /* sdiv */
459 COSTS_N_INSNS (11), /* ddiv */
460 32, /* cache line size */
466 /* Instruction costs on PPC440 processors. */
468 struct processor_costs ppc440_cost = {
469 COSTS_N_INSNS (3), /* mulsi */
470 COSTS_N_INSNS (2), /* mulsi_const */
471 COSTS_N_INSNS (2), /* mulsi_const9 */
472 COSTS_N_INSNS (3), /* muldi */
473 COSTS_N_INSNS (34), /* divsi */
474 COSTS_N_INSNS (34), /* divdi */
475 COSTS_N_INSNS (5), /* fp */
476 COSTS_N_INSNS (5), /* dmul */
477 COSTS_N_INSNS (19), /* sdiv */
478 COSTS_N_INSNS (33), /* ddiv */
479 32, /* cache line size */
485 /* Instruction costs on PPC476 processors. */
487 struct processor_costs ppc476_cost = {
488 COSTS_N_INSNS (4), /* mulsi */
489 COSTS_N_INSNS (4), /* mulsi_const */
490 COSTS_N_INSNS (4), /* mulsi_const9 */
491 COSTS_N_INSNS (4), /* muldi */
492 COSTS_N_INSNS (11), /* divsi */
493 COSTS_N_INSNS (11), /* divdi */
494 COSTS_N_INSNS (6), /* fp */
495 COSTS_N_INSNS (6), /* dmul */
496 COSTS_N_INSNS (19), /* sdiv */
497 COSTS_N_INSNS (33), /* ddiv */
498 32, /* l1 cache line size */
504 /* Instruction costs on PPC601 processors. */
506 struct processor_costs ppc601_cost = {
507 COSTS_N_INSNS (5), /* mulsi */
508 COSTS_N_INSNS (5), /* mulsi_const */
509 COSTS_N_INSNS (5), /* mulsi_const9 */
510 COSTS_N_INSNS (5), /* muldi */
511 COSTS_N_INSNS (36), /* divsi */
512 COSTS_N_INSNS (36), /* divdi */
513 COSTS_N_INSNS (4), /* fp */
514 COSTS_N_INSNS (5), /* dmul */
515 COSTS_N_INSNS (17), /* sdiv */
516 COSTS_N_INSNS (31), /* ddiv */
517 32, /* cache line size */
523 /* Instruction costs on PPC603 processors. */
525 struct processor_costs ppc603_cost = {
526 COSTS_N_INSNS (5), /* mulsi */
527 COSTS_N_INSNS (3), /* mulsi_const */
528 COSTS_N_INSNS (2), /* mulsi_const9 */
529 COSTS_N_INSNS (5), /* muldi */
530 COSTS_N_INSNS (37), /* divsi */
531 COSTS_N_INSNS (37), /* divdi */
532 COSTS_N_INSNS (3), /* fp */
533 COSTS_N_INSNS (4), /* dmul */
534 COSTS_N_INSNS (18), /* sdiv */
535 COSTS_N_INSNS (33), /* ddiv */
536 32, /* cache line size */
542 /* Instruction costs on PPC604 processors. */
544 struct processor_costs ppc604_cost = {
545 COSTS_N_INSNS (4), /* mulsi */
546 COSTS_N_INSNS (4), /* mulsi_const */
547 COSTS_N_INSNS (4), /* mulsi_const9 */
548 COSTS_N_INSNS (4), /* muldi */
549 COSTS_N_INSNS (20), /* divsi */
550 COSTS_N_INSNS (20), /* divdi */
551 COSTS_N_INSNS (3), /* fp */
552 COSTS_N_INSNS (3), /* dmul */
553 COSTS_N_INSNS (18), /* sdiv */
554 COSTS_N_INSNS (32), /* ddiv */
555 32, /* cache line size */
561 /* Instruction costs on PPC604e processors. */
563 struct processor_costs ppc604e_cost = {
564 COSTS_N_INSNS (2), /* mulsi */
565 COSTS_N_INSNS (2), /* mulsi_const */
566 COSTS_N_INSNS (2), /* mulsi_const9 */
567 COSTS_N_INSNS (2), /* muldi */
568 COSTS_N_INSNS (20), /* divsi */
569 COSTS_N_INSNS (20), /* divdi */
570 COSTS_N_INSNS (3), /* fp */
571 COSTS_N_INSNS (3), /* dmul */
572 COSTS_N_INSNS (18), /* sdiv */
573 COSTS_N_INSNS (32), /* ddiv */
574 32, /* cache line size */
580 /* Instruction costs on PPC620 processors. */
582 struct processor_costs ppc620_cost = {
583 COSTS_N_INSNS (5), /* mulsi */
584 COSTS_N_INSNS (4), /* mulsi_const */
585 COSTS_N_INSNS (3), /* mulsi_const9 */
586 COSTS_N_INSNS (7), /* muldi */
587 COSTS_N_INSNS (21), /* divsi */
588 COSTS_N_INSNS (37), /* divdi */
589 COSTS_N_INSNS (3), /* fp */
590 COSTS_N_INSNS (3), /* dmul */
591 COSTS_N_INSNS (18), /* sdiv */
592 COSTS_N_INSNS (32), /* ddiv */
593 128, /* cache line size */
599 /* Instruction costs on PPC630 processors. */
601 struct processor_costs ppc630_cost = {
602 COSTS_N_INSNS (5), /* mulsi */
603 COSTS_N_INSNS (4), /* mulsi_const */
604 COSTS_N_INSNS (3), /* mulsi_const9 */
605 COSTS_N_INSNS (7), /* muldi */
606 COSTS_N_INSNS (21), /* divsi */
607 COSTS_N_INSNS (37), /* divdi */
608 COSTS_N_INSNS (3), /* fp */
609 COSTS_N_INSNS (3), /* dmul */
610 COSTS_N_INSNS (17), /* sdiv */
611 COSTS_N_INSNS (21), /* ddiv */
612 128, /* cache line size */
618 /* Instruction costs on Cell processor. */
619 /* COSTS_N_INSNS (1) ~ one add. */
621 struct processor_costs ppccell_cost = {
622 COSTS_N_INSNS (9/2)+2, /* mulsi */
623 COSTS_N_INSNS (6/2), /* mulsi_const */
624 COSTS_N_INSNS (6/2), /* mulsi_const9 */
625 COSTS_N_INSNS (15/2)+2, /* muldi */
626 COSTS_N_INSNS (38/2), /* divsi */
627 COSTS_N_INSNS (70/2), /* divdi */
628 COSTS_N_INSNS (10/2), /* fp */
629 COSTS_N_INSNS (10/2), /* dmul */
630 COSTS_N_INSNS (74/2), /* sdiv */
631 COSTS_N_INSNS (74/2), /* ddiv */
632 128, /* cache line size */
638 /* Instruction costs on PPC750 and PPC7400 processors. */
640 struct processor_costs ppc750_cost = {
641 COSTS_N_INSNS (5), /* mulsi */
642 COSTS_N_INSNS (3), /* mulsi_const */
643 COSTS_N_INSNS (2), /* mulsi_const9 */
644 COSTS_N_INSNS (5), /* muldi */
645 COSTS_N_INSNS (17), /* divsi */
646 COSTS_N_INSNS (17), /* divdi */
647 COSTS_N_INSNS (3), /* fp */
648 COSTS_N_INSNS (3), /* dmul */
649 COSTS_N_INSNS (17), /* sdiv */
650 COSTS_N_INSNS (31), /* ddiv */
651 32, /* cache line size */
657 /* Instruction costs on PPC7450 processors. */
659 struct processor_costs ppc7450_cost = {
660 COSTS_N_INSNS (4), /* mulsi */
661 COSTS_N_INSNS (3), /* mulsi_const */
662 COSTS_N_INSNS (3), /* mulsi_const9 */
663 COSTS_N_INSNS (4), /* muldi */
664 COSTS_N_INSNS (23), /* divsi */
665 COSTS_N_INSNS (23), /* divdi */
666 COSTS_N_INSNS (5), /* fp */
667 COSTS_N_INSNS (5), /* dmul */
668 COSTS_N_INSNS (21), /* sdiv */
669 COSTS_N_INSNS (35), /* ddiv */
670 32, /* cache line size */
676 /* Instruction costs on PPC8540 processors. */
678 struct processor_costs ppc8540_cost = {
679 COSTS_N_INSNS (4), /* mulsi */
680 COSTS_N_INSNS (4), /* mulsi_const */
681 COSTS_N_INSNS (4), /* mulsi_const9 */
682 COSTS_N_INSNS (4), /* muldi */
683 COSTS_N_INSNS (19), /* divsi */
684 COSTS_N_INSNS (19), /* divdi */
685 COSTS_N_INSNS (4), /* fp */
686 COSTS_N_INSNS (4), /* dmul */
687 COSTS_N_INSNS (29), /* sdiv */
688 COSTS_N_INSNS (29), /* ddiv */
689 32, /* cache line size */
692 1, /* prefetch streams /*/
695 /* Instruction costs on E300C2 and E300C3 cores. */
697 struct processor_costs ppce300c2c3_cost = {
698 COSTS_N_INSNS (4), /* mulsi */
699 COSTS_N_INSNS (4), /* mulsi_const */
700 COSTS_N_INSNS (4), /* mulsi_const9 */
701 COSTS_N_INSNS (4), /* muldi */
702 COSTS_N_INSNS (19), /* divsi */
703 COSTS_N_INSNS (19), /* divdi */
704 COSTS_N_INSNS (3), /* fp */
705 COSTS_N_INSNS (4), /* dmul */
706 COSTS_N_INSNS (18), /* sdiv */
707 COSTS_N_INSNS (33), /* ddiv */
711 1, /* prefetch streams /*/
714 /* Instruction costs on PPCE500MC processors. */
716 struct processor_costs ppce500mc_cost = {
717 COSTS_N_INSNS (4), /* mulsi */
718 COSTS_N_INSNS (4), /* mulsi_const */
719 COSTS_N_INSNS (4), /* mulsi_const9 */
720 COSTS_N_INSNS (4), /* muldi */
721 COSTS_N_INSNS (14), /* divsi */
722 COSTS_N_INSNS (14), /* divdi */
723 COSTS_N_INSNS (8), /* fp */
724 COSTS_N_INSNS (10), /* dmul */
725 COSTS_N_INSNS (36), /* sdiv */
726 COSTS_N_INSNS (66), /* ddiv */
727 64, /* cache line size */
730 1, /* prefetch streams /*/
733 /* Instruction costs on PPCE500MC64 processors. */
735 struct processor_costs ppce500mc64_cost = {
736 COSTS_N_INSNS (4), /* mulsi */
737 COSTS_N_INSNS (4), /* mulsi_const */
738 COSTS_N_INSNS (4), /* mulsi_const9 */
739 COSTS_N_INSNS (4), /* muldi */
740 COSTS_N_INSNS (14), /* divsi */
741 COSTS_N_INSNS (14), /* divdi */
742 COSTS_N_INSNS (4), /* fp */
743 COSTS_N_INSNS (10), /* dmul */
744 COSTS_N_INSNS (36), /* sdiv */
745 COSTS_N_INSNS (66), /* ddiv */
746 64, /* cache line size */
749 1, /* prefetch streams /*/
752 /* Instruction costs on AppliedMicro Titan processors. */
754 struct processor_costs titan_cost = {
755 COSTS_N_INSNS (5), /* mulsi */
756 COSTS_N_INSNS (5), /* mulsi_const */
757 COSTS_N_INSNS (5), /* mulsi_const9 */
758 COSTS_N_INSNS (5), /* muldi */
759 COSTS_N_INSNS (18), /* divsi */
760 COSTS_N_INSNS (18), /* divdi */
761 COSTS_N_INSNS (10), /* fp */
762 COSTS_N_INSNS (10), /* dmul */
763 COSTS_N_INSNS (46), /* sdiv */
764 COSTS_N_INSNS (72), /* ddiv */
765 32, /* cache line size */
768 1, /* prefetch streams /*/
771 /* Instruction costs on POWER4 and POWER5 processors. */
773 struct processor_costs power4_cost = {
774 COSTS_N_INSNS (3), /* mulsi */
775 COSTS_N_INSNS (2), /* mulsi_const */
776 COSTS_N_INSNS (2), /* mulsi_const9 */
777 COSTS_N_INSNS (4), /* muldi */
778 COSTS_N_INSNS (18), /* divsi */
779 COSTS_N_INSNS (34), /* divdi */
780 COSTS_N_INSNS (3), /* fp */
781 COSTS_N_INSNS (3), /* dmul */
782 COSTS_N_INSNS (17), /* sdiv */
783 COSTS_N_INSNS (17), /* ddiv */
784 128, /* cache line size */
787 8, /* prefetch streams /*/
790 /* Instruction costs on POWER6 processors. */
792 struct processor_costs power6_cost = {
793 COSTS_N_INSNS (8), /* mulsi */
794 COSTS_N_INSNS (8), /* mulsi_const */
795 COSTS_N_INSNS (8), /* mulsi_const9 */
796 COSTS_N_INSNS (8), /* muldi */
797 COSTS_N_INSNS (22), /* divsi */
798 COSTS_N_INSNS (28), /* divdi */
799 COSTS_N_INSNS (3), /* fp */
800 COSTS_N_INSNS (3), /* dmul */
801 COSTS_N_INSNS (13), /* sdiv */
802 COSTS_N_INSNS (16), /* ddiv */
803 128, /* cache line size */
806 16, /* prefetch streams */
809 /* Instruction costs on POWER7 processors. */
811 struct processor_costs power7_cost = {
812 COSTS_N_INSNS (2), /* mulsi */
813 COSTS_N_INSNS (2), /* mulsi_const */
814 COSTS_N_INSNS (2), /* mulsi_const9 */
815 COSTS_N_INSNS (2), /* muldi */
816 COSTS_N_INSNS (18), /* divsi */
817 COSTS_N_INSNS (34), /* divdi */
818 COSTS_N_INSNS (3), /* fp */
819 COSTS_N_INSNS (3), /* dmul */
820 COSTS_N_INSNS (13), /* sdiv */
821 COSTS_N_INSNS (16), /* ddiv */
822 128, /* cache line size */
825 12, /* prefetch streams */
828 /* Instruction costs on POWER A2 processors. */
830 struct processor_costs ppca2_cost = {
831 COSTS_N_INSNS (16), /* mulsi */
832 COSTS_N_INSNS (16), /* mulsi_const */
833 COSTS_N_INSNS (16), /* mulsi_const9 */
834 COSTS_N_INSNS (16), /* muldi */
835 COSTS_N_INSNS (22), /* divsi */
836 COSTS_N_INSNS (28), /* divdi */
837 COSTS_N_INSNS (3), /* fp */
838 COSTS_N_INSNS (3), /* dmul */
839 COSTS_N_INSNS (59), /* sdiv */
840 COSTS_N_INSNS (72), /* ddiv */
844 16, /* prefetch streams */
848 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
849 #undef RS6000_BUILTIN
850 #undef RS6000_BUILTIN_EQUATE
851 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
852 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
854 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
856 #include "rs6000-builtin.def"
859 #undef RS6000_BUILTIN
860 #undef RS6000_BUILTIN_EQUATE
862 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
863 static tree (*rs6000_veclib_handler) (tree, tree, tree);
866 static bool rs6000_function_ok_for_sibcall (tree, tree);
867 static const char *rs6000_invalid_within_doloop (const_rtx);
868 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
869 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
870 static rtx rs6000_generate_compare (rtx, enum machine_mode);
871 static void rs6000_emit_stack_tie (void);
872 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
873 static bool spe_func_has_64bit_regs_p (void);
874 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
876 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
877 static unsigned rs6000_hash_constant (rtx);
878 static unsigned toc_hash_function (const void *);
879 static int toc_hash_eq (const void *, const void *);
880 static bool reg_offset_addressing_ok_p (enum machine_mode);
881 static bool virtual_stack_registers_memory_p (rtx);
882 static bool constant_pool_expr_p (rtx);
883 static bool legitimate_small_data_p (enum machine_mode, rtx);
884 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
885 static struct machine_function * rs6000_init_machine_status (void);
886 static bool rs6000_assemble_integer (rtx, unsigned int, int);
887 static bool no_global_regs_above (int, bool);
888 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
889 static void rs6000_assemble_visibility (tree, int);
891 static int rs6000_ra_ever_killed (void);
892 static bool rs6000_attribute_takes_identifier_p (const_tree);
893 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
894 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
895 static bool rs6000_ms_bitfield_layout_p (const_tree);
896 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
897 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
898 static const char *rs6000_mangle_type (const_tree);
899 static void rs6000_set_default_type_attributes (tree);
900 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
901 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
902 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
903 enum machine_mode, bool, bool, bool);
904 static bool rs6000_reg_live_or_pic_offset_p (int);
905 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
906 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
907 static void rs6000_restore_saved_cr (rtx, int);
908 static bool rs6000_output_addr_const_extra (FILE *, rtx);
909 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
910 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
911 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
913 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
914 static bool rs6000_return_in_memory (const_tree, const_tree);
915 static rtx rs6000_function_value (const_tree, const_tree, bool);
916 static void rs6000_file_start (void);
918 static int rs6000_elf_reloc_rw_mask (void);
919 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
920 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
921 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
922 static void rs6000_elf_asm_init_sections (void);
923 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
924 unsigned HOST_WIDE_INT);
925 static void rs6000_elf_encode_section_info (tree, rtx, int)
928 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
929 static void rs6000_alloc_sdmode_stack_slot (void);
930 static void rs6000_instantiate_decls (void);
932 static void rs6000_xcoff_asm_output_anchor (rtx);
933 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
934 static void rs6000_xcoff_asm_init_sections (void);
935 static int rs6000_xcoff_reloc_rw_mask (void);
936 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
937 static section *rs6000_xcoff_select_section (tree, int,
938 unsigned HOST_WIDE_INT);
939 static void rs6000_xcoff_unique_section (tree, int);
940 static section *rs6000_xcoff_select_rtx_section
941 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
942 static const char * rs6000_xcoff_strip_name_encoding (const char *);
943 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
944 static void rs6000_xcoff_file_start (void);
945 static void rs6000_xcoff_file_end (void);
947 static int rs6000_variable_issue (FILE *, int, rtx, int);
948 static int rs6000_register_move_cost (enum machine_mode,
949 reg_class_t, reg_class_t);
950 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
951 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
952 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
953 static int rs6000_debug_address_cost (rtx, bool);
954 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
955 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
956 static void rs6000_sched_init (FILE *, int, int);
957 static bool is_microcoded_insn (rtx);
958 static bool is_nonpipeline_insn (rtx);
959 static bool is_cracked_insn (rtx);
960 static bool is_branch_slot_insn (rtx);
961 static bool is_load_insn (rtx);
962 static rtx get_store_dest (rtx pat);
963 static bool is_store_insn (rtx);
964 static bool set_to_load_agen (rtx,rtx);
965 static bool adjacent_mem_locations (rtx,rtx);
966 static int rs6000_adjust_priority (rtx, int);
967 static int rs6000_issue_rate (void);
968 static bool rs6000_is_costly_dependence (dep_t, int, int);
969 static rtx get_next_active_insn (rtx, rtx);
970 static bool insn_terminates_group_p (rtx , enum group_termination);
971 static bool insn_must_be_first_in_group (rtx);
972 static bool insn_must_be_last_in_group (rtx);
973 static bool is_costly_group (rtx *, rtx);
974 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
975 static int redefine_groups (FILE *, int, rtx, rtx);
976 static int pad_groups (FILE *, int, rtx, rtx);
977 static void rs6000_sched_finish (FILE *, int);
978 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
979 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
980 static int rs6000_use_sched_lookahead (void);
981 static int rs6000_use_sched_lookahead_guard (rtx);
982 static void * rs6000_alloc_sched_context (void);
983 static void rs6000_init_sched_context (void *, bool);
984 static void rs6000_set_sched_context (void *);
985 static void rs6000_free_sched_context (void *);
986 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
987 static tree rs6000_builtin_mask_for_load (void);
988 static tree rs6000_builtin_mul_widen_even (tree);
989 static tree rs6000_builtin_mul_widen_odd (tree);
990 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
991 static tree rs6000_builtin_vec_perm (tree, tree *);
992 static bool rs6000_builtin_support_vector_misalignment (enum
996 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
998 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1000 static void def_builtin (int, const char *, tree, int);
1001 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1002 static void rs6000_init_builtins (void);
1003 static tree rs6000_builtin_decl (unsigned, bool);
1005 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1006 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1007 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1008 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1009 static void altivec_init_builtins (void);
1010 static unsigned builtin_hash_function (const void *);
1011 static int builtin_hash_eq (const void *, const void *);
1012 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1013 enum machine_mode, enum machine_mode,
1014 enum rs6000_builtins, const char *name);
1015 static void rs6000_common_init_builtins (void);
1016 static void rs6000_init_libfuncs (void);
1018 static void paired_init_builtins (void);
1019 static rtx paired_expand_builtin (tree, rtx, bool *);
1020 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1021 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1022 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1024 static void enable_mask_for_builtins (struct builtin_description *, int,
1025 enum rs6000_builtins,
1026 enum rs6000_builtins);
1027 static void spe_init_builtins (void);
1028 static rtx spe_expand_builtin (tree, rtx, bool *);
1029 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1030 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1031 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1032 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1033 static rs6000_stack_t *rs6000_stack_info (void);
1034 static void debug_stack_info (rs6000_stack_t *);
1036 static rtx altivec_expand_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1038 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1039 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1041 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1042 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1043 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1044 static rtx altivec_expand_vec_set_builtin (tree);
1045 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1046 static int get_element_number (tree, tree);
1047 static void rs6000_option_override (void);
1048 static void rs6000_option_default_params (void);
1049 static int rs6000_loop_align_max_skip (rtx);
1050 static int first_altivec_reg_to_save (void);
1051 static unsigned int compute_vrsave_mask (void);
1052 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1053 static void is_altivec_return_reg (rtx, void *);
1054 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1055 int easy_vector_constant (rtx, enum machine_mode);
1056 static rtx rs6000_dwarf_register_span (rtx);
1057 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1058 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1059 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1060 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1061 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1062 static rtx rs6000_delegitimize_address (rtx);
1063 static rtx rs6000_tls_get_addr (void);
1064 static rtx rs6000_got_sym (void);
1065 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1066 static const char *rs6000_get_some_local_dynamic_name (void);
1067 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1068 static rtx rs6000_complex_function_value (enum machine_mode);
1069 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1070 enum machine_mode, const_tree);
1071 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1072 HOST_WIDE_INT, int);
1073 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1076 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1079 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1080 const_tree, HOST_WIDE_INT,
1082 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1083 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1084 static void rs6000_function_arg_advance (cumulative_args_t, enum machine_mode,
1086 static rtx rs6000_function_arg (cumulative_args_t, enum machine_mode,
1088 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1090 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1091 static void setup_incoming_varargs (cumulative_args_t,
1092 enum machine_mode, tree,
1094 static bool rs6000_pass_by_reference (cumulative_args_t, enum machine_mode,
1096 static int rs6000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
1098 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1100 static void macho_branch_islands (void);
1101 static int no_previous_def (tree function_name);
1102 static tree get_prev_label (tree function_name);
1103 static void rs6000_darwin_file_start (void);
1106 static tree rs6000_build_builtin_va_list (void);
1107 static void rs6000_va_start (tree, rtx);
1108 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1109 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1110 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1111 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1112 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1113 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1115 static tree rs6000_stack_protect_fail (void);
1117 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1120 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1123 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1125 = rs6000_legitimize_reload_address;
1127 static bool rs6000_mode_dependent_address_p (const_rtx);
1128 static bool rs6000_mode_dependent_address (const_rtx);
1129 static bool rs6000_debug_mode_dependent_address (const_rtx);
1130 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1131 = rs6000_mode_dependent_address;
1133 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1134 enum machine_mode, rtx);
1135 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1138 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1139 enum machine_mode, rtx)
1140 = rs6000_secondary_reload_class;
1142 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1143 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1145 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1146 = rs6000_preferred_reload_class;
1148 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1151 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1155 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1157 = rs6000_secondary_memory_needed;
1159 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1162 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1166 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1169 = rs6000_cannot_change_mode_class;
1171 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1173 struct secondary_reload_info *);
1175 const int INSN_NOT_AVAILABLE = -1;
1176 static enum machine_mode rs6000_eh_return_filter_mode (void);
1177 static bool rs6000_can_eliminate (const int, const int);
1178 static void rs6000_conditional_register_usage (void);
1179 static void rs6000_trampoline_init (rtx, tree, rtx);
1180 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1181 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1183 /* Hash table stuff for keeping track of TOC entries. */
1185 struct GTY(()) toc_hash_struct
1187 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1188 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1190 enum machine_mode key_mode;
1194 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1196 /* Hash table to keep track of the argument types for builtin functions. */
1198 struct GTY(()) builtin_hash_struct
1201 enum machine_mode mode[4]; /* return value + 3 arguments. */
1202 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1205 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1207 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1208 static void rs6000_function_specific_save (struct cl_target_option *);
1209 static void rs6000_function_specific_restore (struct cl_target_option *);
1210 static void rs6000_function_specific_print (FILE *, int,
1211 struct cl_target_option *);
1212 static bool rs6000_can_inline_p (tree, tree);
1213 static void rs6000_set_current_function (tree);
1216 /* Default register names. */
1217 char rs6000_reg_names[][8] =
1219 "0", "1", "2", "3", "4", "5", "6", "7",
1220 "8", "9", "10", "11", "12", "13", "14", "15",
1221 "16", "17", "18", "19", "20", "21", "22", "23",
1222 "24", "25", "26", "27", "28", "29", "30", "31",
1223 "0", "1", "2", "3", "4", "5", "6", "7",
1224 "8", "9", "10", "11", "12", "13", "14", "15",
1225 "16", "17", "18", "19", "20", "21", "22", "23",
1226 "24", "25", "26", "27", "28", "29", "30", "31",
1227 "mq", "lr", "ctr","ap",
1228 "0", "1", "2", "3", "4", "5", "6", "7",
1230 /* AltiVec registers. */
1231 "0", "1", "2", "3", "4", "5", "6", "7",
1232 "8", "9", "10", "11", "12", "13", "14", "15",
1233 "16", "17", "18", "19", "20", "21", "22", "23",
1234 "24", "25", "26", "27", "28", "29", "30", "31",
1236 /* SPE registers. */
1237 "spe_acc", "spefscr",
1238 /* Soft frame pointer. */
1242 #ifdef TARGET_REGNAMES
1243 static const char alt_reg_names[][8] =
1245 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1246 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1247 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1248 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1249 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1250 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1251 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1252 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1253 "mq", "lr", "ctr", "ap",
1254 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1256 /* AltiVec registers. */
1257 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1258 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1259 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1260 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1262 /* SPE registers. */
1263 "spe_acc", "spefscr",
1264 /* Soft frame pointer. */
1269 /* Table of valid machine attributes. */
1271 static const struct attribute_spec rs6000_attribute_table[] =
1273 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1274 affects_type_identity } */
1275 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1277 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1279 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1281 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1283 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1285 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1286 SUBTARGET_ATTRIBUTE_TABLE,
1288 { NULL, 0, 0, false, false, false, NULL, false }
1291 #ifndef MASK_STRICT_ALIGN
1292 #define MASK_STRICT_ALIGN 0
1294 #ifndef TARGET_PROFILE_KERNEL
1295 #define TARGET_PROFILE_KERNEL 0
1298 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1299 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1301 /* Initialize the GCC target structure. */
1302 #undef TARGET_ATTRIBUTE_TABLE
1303 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1304 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1305 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1306 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1307 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1309 #undef TARGET_ASM_ALIGNED_DI_OP
1310 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1312 /* Default unaligned ops are only provided for ELF. Find the ops needed
1313 for non-ELF systems. */
1314 #ifndef OBJECT_FORMAT_ELF
1316 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1318 #undef TARGET_ASM_UNALIGNED_HI_OP
1319 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1320 #undef TARGET_ASM_UNALIGNED_SI_OP
1321 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1322 #undef TARGET_ASM_UNALIGNED_DI_OP
1323 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1326 #undef TARGET_ASM_UNALIGNED_HI_OP
1327 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1328 #undef TARGET_ASM_UNALIGNED_SI_OP
1329 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1330 #undef TARGET_ASM_UNALIGNED_DI_OP
1331 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1332 #undef TARGET_ASM_ALIGNED_DI_OP
1333 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1337 /* This hook deals with fixups for relocatable code and DI-mode objects
1339 #undef TARGET_ASM_INTEGER
1340 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1342 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
1343 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1344 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1347 #undef TARGET_HAVE_TLS
1348 #define TARGET_HAVE_TLS HAVE_AS_TLS
1350 #undef TARGET_CANNOT_FORCE_CONST_MEM
1351 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1353 #undef TARGET_DELEGITIMIZE_ADDRESS
1354 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1356 #undef TARGET_ASM_FUNCTION_PROLOGUE
1357 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1358 #undef TARGET_ASM_FUNCTION_EPILOGUE
1359 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1361 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1362 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1364 #undef TARGET_LEGITIMIZE_ADDRESS
1365 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1367 #undef TARGET_SCHED_VARIABLE_ISSUE
1368 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1370 #undef TARGET_SCHED_ISSUE_RATE
1371 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1372 #undef TARGET_SCHED_ADJUST_COST
1373 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1374 #undef TARGET_SCHED_ADJUST_PRIORITY
1375 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1376 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1377 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1378 #undef TARGET_SCHED_INIT
1379 #define TARGET_SCHED_INIT rs6000_sched_init
1380 #undef TARGET_SCHED_FINISH
1381 #define TARGET_SCHED_FINISH rs6000_sched_finish
1382 #undef TARGET_SCHED_REORDER
1383 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1384 #undef TARGET_SCHED_REORDER2
1385 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1387 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1388 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1390 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1391 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1393 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1394 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1395 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1396 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1397 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1398 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1399 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1400 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1402 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1403 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1404 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1405 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1406 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1407 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1408 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1409 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1410 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1411 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1412 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1413 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1414 rs6000_builtin_support_vector_misalignment
1415 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1416 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1417 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1418 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1419 rs6000_builtin_vectorization_cost
1420 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1421 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1422 rs6000_preferred_simd_mode
1424 #undef TARGET_INIT_BUILTINS
1425 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1426 #undef TARGET_BUILTIN_DECL
1427 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1429 #undef TARGET_EXPAND_BUILTIN
1430 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1432 #undef TARGET_MANGLE_TYPE
1433 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1435 #undef TARGET_INIT_LIBFUNCS
1436 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1439 #undef TARGET_BINDS_LOCAL_P
1440 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1443 #undef TARGET_MS_BITFIELD_LAYOUT_P
1444 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1446 #undef TARGET_ASM_OUTPUT_MI_THUNK
1447 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1449 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1450 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1452 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1453 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1455 #undef TARGET_INVALID_WITHIN_DOLOOP
1456 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1458 #undef TARGET_REGISTER_MOVE_COST
1459 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1460 #undef TARGET_MEMORY_MOVE_COST
1461 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1462 #undef TARGET_RTX_COSTS
1463 #define TARGET_RTX_COSTS rs6000_rtx_costs
1464 #undef TARGET_ADDRESS_COST
1465 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1467 #undef TARGET_DWARF_REGISTER_SPAN
1468 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1470 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1471 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1473 /* On rs6000, function arguments are promoted, as are function return
1475 #undef TARGET_PROMOTE_FUNCTION_MODE
1476 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1478 #undef TARGET_RETURN_IN_MEMORY
1479 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1481 #undef TARGET_SETUP_INCOMING_VARARGS
1482 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1484 /* Always strict argument naming on rs6000. */
1485 #undef TARGET_STRICT_ARGUMENT_NAMING
1486 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1487 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1488 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1489 #undef TARGET_SPLIT_COMPLEX_ARG
1490 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1491 #undef TARGET_MUST_PASS_IN_STACK
1492 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1493 #undef TARGET_PASS_BY_REFERENCE
1494 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1495 #undef TARGET_ARG_PARTIAL_BYTES
1496 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1497 #undef TARGET_FUNCTION_ARG_ADVANCE
1498 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1499 #undef TARGET_FUNCTION_ARG
1500 #define TARGET_FUNCTION_ARG rs6000_function_arg
1501 #undef TARGET_FUNCTION_ARG_BOUNDARY
1502 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1504 #undef TARGET_BUILD_BUILTIN_VA_LIST
1505 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1507 #undef TARGET_EXPAND_BUILTIN_VA_START
1508 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1510 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1511 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1513 #undef TARGET_EH_RETURN_FILTER_MODE
1514 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1516 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1517 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1519 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1520 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1522 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1523 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1525 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1526 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1528 #undef TARGET_OPTION_OVERRIDE
1529 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1531 #undef TARGET_OPTION_DEFAULT_PARAMS
1532 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1534 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1535 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1536 rs6000_builtin_vectorized_function
1538 #ifndef TARGET_MACHO
1539 #undef TARGET_STACK_PROTECT_FAIL
1540 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1543 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1544 The PowerPC architecture requires only weak consistency among
1545 processors--that is, memory accesses between processors need not be
1546 sequentially consistent and memory accesses among processors can occur
1547 in any order. The ability to order memory accesses weakly provides
1548 opportunities for more efficient use of the system bus. Unless a
1549 dependency exists, the 604e allows read operations to precede store
1551 #undef TARGET_RELAXED_ORDERING
1552 #define TARGET_RELAXED_ORDERING true
1555 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1556 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1559 /* Use a 32-bit anchor range. This leads to sequences like:
1561 addis tmp,anchor,high
1564 where tmp itself acts as an anchor, and can be shared between
1565 accesses to the same 64k page. */
1566 #undef TARGET_MIN_ANCHOR_OFFSET
1567 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1568 #undef TARGET_MAX_ANCHOR_OFFSET
1569 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1570 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1571 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1573 #undef TARGET_BUILTIN_RECIPROCAL
1574 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1576 #undef TARGET_EXPAND_TO_RTL_HOOK
1577 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1579 #undef TARGET_INSTANTIATE_DECLS
1580 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1582 #undef TARGET_SECONDARY_RELOAD
1583 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1585 #undef TARGET_LEGITIMATE_ADDRESS_P
1586 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1588 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1589 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1591 #undef TARGET_CAN_ELIMINATE
1592 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1594 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1595 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1597 #undef TARGET_TRAMPOLINE_INIT
1598 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1600 #undef TARGET_FUNCTION_VALUE
1601 #define TARGET_FUNCTION_VALUE rs6000_function_value
1603 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1604 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1606 #undef TARGET_OPTION_SAVE
1607 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1609 #undef TARGET_OPTION_RESTORE
1610 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1612 #undef TARGET_OPTION_PRINT
1613 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1615 #undef TARGET_CAN_INLINE_P
1616 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1618 #undef TARGET_SET_CURRENT_FUNCTION
1619 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1621 #undef TARGET_LEGITIMATE_CONSTANT_P
1622 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1624 struct gcc_target targetm = TARGET_INITIALIZER;
1627 /* Simplifications for entries below. */
1630 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1631 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1634 /* Some OSs don't support saving the high part of 64-bit registers on context
1635 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1636 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1637 either, the user must explicitly specify them and we won't interfere with
1638 the user's specification. */
1641 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1642 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1643 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1644 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1645 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1646 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1647 | MASK_RECIP_PRECISION)
1650 /* Masks for instructions set at various powerpc ISAs. */
1652 ISA_2_1_MASKS = MASK_MFCRF,
1653 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1654 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1656 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1657 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1658 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1659 server and embedded. */
1660 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1661 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1662 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1664 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1665 altivec is a win so enable it. */
1666 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1667 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1673 const char *const name; /* Canonical processor name. */
1674 const enum processor_type processor; /* Processor type enum value. */
1675 const int target_enable; /* Target flags to enable. */
1678 static struct rs6000_ptt const processor_target_table[] =
1680 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1681 #include "rs6000-cpus.def"
1685 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1689 rs6000_cpu_name_lookup (const char *name)
1695 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1696 if (! strcmp (name, processor_target_table[i].name))
1704 /* Return number of consecutive hard regs needed starting at reg REGNO
1705 to hold something of mode MODE.
1706 This is ordinarily the length in words of a value of mode MODE
1707 but can be less for certain modes in special long registers.
1709 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1710 scalar instructions. The upper 32 bits are only available to the
1713 POWER and PowerPC GPRs hold 32 bits worth;
1714 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1717 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1719 unsigned HOST_WIDE_INT reg_size;
1721 if (FP_REGNO_P (regno))
1722 reg_size = (VECTOR_MEM_VSX_P (mode)
1723 ? UNITS_PER_VSX_WORD
1724 : UNITS_PER_FP_WORD);
1726 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1727 reg_size = UNITS_PER_SPE_WORD;
1729 else if (ALTIVEC_REGNO_P (regno))
1730 reg_size = UNITS_PER_ALTIVEC_WORD;
1732 /* The value returned for SCmode in the E500 double case is 2 for
1733 ABI compatibility; storing an SCmode value in a single register
1734 would require function_arg and rs6000_spe_function_arg to handle
1735 SCmode so as to pass the value correctly in a pair of
1737 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1738 && !DECIMAL_FLOAT_MODE_P (mode))
1739 reg_size = UNITS_PER_FP_WORD;
1742 reg_size = UNITS_PER_WORD;
1744 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1747 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1750 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1752 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1754 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1755 implementations. Don't allow an item to be split between a FP register
1756 and an Altivec register. */
1757 if (VECTOR_MEM_VSX_P (mode))
1759 if (FP_REGNO_P (regno))
1760 return FP_REGNO_P (last_regno);
1762 if (ALTIVEC_REGNO_P (regno))
1763 return ALTIVEC_REGNO_P (last_regno);
1766 /* The GPRs can hold any mode, but values bigger than one register
1767 cannot go past R31. */
1768 if (INT_REGNO_P (regno))
1769 return INT_REGNO_P (last_regno);
1771 /* The float registers (except for VSX vector modes) can only hold floating
1772 modes and DImode. This excludes the 32-bit decimal float mode for
1774 if (FP_REGNO_P (regno))
1776 if (SCALAR_FLOAT_MODE_P (mode)
1777 && (mode != TDmode || (regno % 2) == 0)
1778 && FP_REGNO_P (last_regno))
1781 if (GET_MODE_CLASS (mode) == MODE_INT
1782 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1785 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1786 && PAIRED_VECTOR_MODE (mode))
1792 /* The CR register can only hold CC modes. */
1793 if (CR_REGNO_P (regno))
1794 return GET_MODE_CLASS (mode) == MODE_CC;
1796 if (CA_REGNO_P (regno))
1797 return mode == BImode;
1799 /* AltiVec only in AldyVec registers. */
1800 if (ALTIVEC_REGNO_P (regno))
1801 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1803 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1804 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1807 /* We cannot put TImode anywhere except general register and it must be able
1808 to fit within the register set. In the future, allow TImode in the
1809 Altivec or VSX registers. */
1811 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1814 /* Print interesting facts about registers. */
1816 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1820 for (r = first_regno; r <= last_regno; ++r)
1822 const char *comma = "";
1825 if (first_regno == last_regno)
1826 fprintf (stderr, "%s:\t", reg_name);
1828 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1831 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1832 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1836 fprintf (stderr, ",\n\t");
1841 if (rs6000_hard_regno_nregs[m][r] > 1)
1842 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1843 rs6000_hard_regno_nregs[m][r]);
1845 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1850 if (call_used_regs[r])
1854 fprintf (stderr, ",\n\t");
1859 len += fprintf (stderr, "%s%s", comma, "call-used");
1867 fprintf (stderr, ",\n\t");
1872 len += fprintf (stderr, "%s%s", comma, "fixed");
1878 fprintf (stderr, ",\n\t");
1882 fprintf (stderr, "%sregno = %d\n", comma, r);
1886 #define DEBUG_FMT_D "%-32s= %d\n"
1887 #define DEBUG_FMT_S "%-32s= %s\n"
1889 /* Print various interesting information with -mdebug=reg. */
1891 rs6000_debug_reg_global (void)
1893 static const char *const tf[2] = { "false", "true" };
1894 const char *nl = (const char *)0;
1896 char costly_num[20];
1898 const char *costly_str;
1899 const char *nop_str;
1900 const char *trace_str;
1901 const char *abi_str;
1902 const char *cmodel_str;
1904 /* Map enum rs6000_vector to string. */
1905 static const char *rs6000_debug_vector_unit[] = {
1914 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1915 LAST_VIRTUAL_REGISTER);
1916 rs6000_debug_reg_print (0, 31, "gr");
1917 rs6000_debug_reg_print (32, 63, "fp");
1918 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1921 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1922 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1923 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1924 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1925 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1926 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1927 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1928 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1929 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1933 "d reg_class = %s\n"
1934 "f reg_class = %s\n"
1935 "v reg_class = %s\n"
1936 "wa reg_class = %s\n"
1937 "wd reg_class = %s\n"
1938 "wf reg_class = %s\n"
1939 "ws reg_class = %s\n\n",
1940 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1941 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1942 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1943 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1944 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1945 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1946 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1948 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1949 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1952 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1954 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1955 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1961 if (rs6000_recip_control)
1963 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1965 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1966 if (rs6000_recip_bits[m])
1969 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1971 (RS6000_RECIP_AUTO_RE_P (m)
1973 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1974 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1976 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1979 fputs ("\n", stderr);
1982 if (rs6000_cpu_index >= 0)
1983 fprintf (stderr, DEBUG_FMT_S, "cpu",
1984 processor_target_table[rs6000_cpu_index].name);
1986 if (rs6000_tune_index >= 0)
1987 fprintf (stderr, DEBUG_FMT_S, "tune",
1988 processor_target_table[rs6000_tune_index].name);
1990 switch (rs6000_sched_costly_dep)
1992 case max_dep_latency:
1993 costly_str = "max_dep_latency";
1997 costly_str = "no_dep_costly";
2000 case all_deps_costly:
2001 costly_str = "all_deps_costly";
2004 case true_store_to_load_dep_costly:
2005 costly_str = "true_store_to_load_dep_costly";
2008 case store_to_load_dep_costly:
2009 costly_str = "store_to_load_dep_costly";
2013 costly_str = costly_num;
2014 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2018 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2020 switch (rs6000_sched_insert_nops)
2022 case sched_finish_regroup_exact:
2023 nop_str = "sched_finish_regroup_exact";
2026 case sched_finish_pad_groups:
2027 nop_str = "sched_finish_pad_groups";
2030 case sched_finish_none:
2031 nop_str = "sched_finish_none";
2036 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2040 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2042 switch (rs6000_sdata)
2049 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2053 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2057 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2062 switch (rs6000_traceback)
2064 case traceback_default: trace_str = "default"; break;
2065 case traceback_none: trace_str = "none"; break;
2066 case traceback_part: trace_str = "part"; break;
2067 case traceback_full: trace_str = "full"; break;
2068 default: trace_str = "unknown"; break;
2071 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2073 switch (rs6000_current_cmodel)
2075 case CMODEL_SMALL: cmodel_str = "small"; break;
2076 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2077 case CMODEL_LARGE: cmodel_str = "large"; break;
2078 default: cmodel_str = "unknown"; break;
2081 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2083 switch (rs6000_current_abi)
2085 case ABI_NONE: abi_str = "none"; break;
2086 case ABI_AIX: abi_str = "aix"; break;
2087 case ABI_V4: abi_str = "V4"; break;
2088 case ABI_DARWIN: abi_str = "darwin"; break;
2089 default: abi_str = "unknown"; break;
2092 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2094 if (rs6000_altivec_abi)
2095 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2098 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2100 if (rs6000_darwin64_abi)
2101 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2103 if (rs6000_float_gprs)
2104 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2106 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2107 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2108 tf[!!rs6000_align_branch_targets]);
2109 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2110 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2111 rs6000_long_double_type_size);
2112 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2113 (int)rs6000_sched_restricted_insns_priority);
2116 /* Initialize the various global tables that are based on register size. */
2118 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2124 /* Precalculate REGNO_REG_CLASS. */
2125 rs6000_regno_regclass[0] = GENERAL_REGS;
2126 for (r = 1; r < 32; ++r)
2127 rs6000_regno_regclass[r] = BASE_REGS;
2129 for (r = 32; r < 64; ++r)
2130 rs6000_regno_regclass[r] = FLOAT_REGS;
2132 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2133 rs6000_regno_regclass[r] = NO_REGS;
2135 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2136 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2138 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2139 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2140 rs6000_regno_regclass[r] = CR_REGS;
2142 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2143 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2144 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2145 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2146 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2147 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2148 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2149 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2150 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2151 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2153 /* Precalculate vector information, this must be set up before the
2154 rs6000_hard_regno_nregs_internal below. */
2155 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2157 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2158 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2159 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2162 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2163 rs6000_constraints[c] = NO_REGS;
2165 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2166 believes it can use native alignment or still uses 128-bit alignment. */
2167 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2178 /* V2DF mode, VSX only. */
2181 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2182 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2183 rs6000_vector_align[V2DFmode] = align64;
2186 /* V4SF mode, either VSX or Altivec. */
2189 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2190 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2191 rs6000_vector_align[V4SFmode] = align32;
2193 else if (TARGET_ALTIVEC)
2195 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2196 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2197 rs6000_vector_align[V4SFmode] = align32;
2200 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2204 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2205 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2206 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2207 rs6000_vector_align[V4SImode] = align32;
2208 rs6000_vector_align[V8HImode] = align32;
2209 rs6000_vector_align[V16QImode] = align32;
2213 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2214 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2215 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2219 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2220 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2221 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2225 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2226 Altivec doesn't have 64-bit support. */
2229 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2230 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2231 rs6000_vector_align[V2DImode] = align64;
2234 /* DFmode, see if we want to use the VSX unit. */
2235 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2237 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2238 rs6000_vector_mem[DFmode]
2239 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2240 rs6000_vector_align[DFmode] = align64;
2243 /* TODO add SPE and paired floating point vector support. */
2245 /* Register class constaints for the constraints that depend on compile
2247 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2248 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2250 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2251 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2255 /* At present, we just use VSX_REGS, but we have different constraints
2256 based on the use, in case we want to fine tune the default register
2257 class used. wa = any VSX register, wf = register class to use for
2258 V4SF, wd = register class to use for V2DF, and ws = register classs to
2259 use for DF scalars. */
2260 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2261 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2262 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2263 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2269 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2271 /* Set up the reload helper functions. */
2272 if (TARGET_VSX || TARGET_ALTIVEC)
2276 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2277 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2278 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2279 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2280 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2281 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2282 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2283 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2284 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2285 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2286 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2287 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2291 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2292 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2293 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2294 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2295 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2296 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2297 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2298 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2299 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2300 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2301 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2302 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2306 /* Precalculate HARD_REGNO_NREGS. */
2307 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2308 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2309 rs6000_hard_regno_nregs[m][r]
2310 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2312 /* Precalculate HARD_REGNO_MODE_OK. */
2313 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2314 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2315 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2316 rs6000_hard_regno_mode_ok_p[m][r] = true;
2318 /* Precalculate CLASS_MAX_NREGS sizes. */
2319 for (c = 0; c < LIM_REG_CLASSES; ++c)
2323 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2324 reg_size = UNITS_PER_VSX_WORD;
2326 else if (c == ALTIVEC_REGS)
2327 reg_size = UNITS_PER_ALTIVEC_WORD;
2329 else if (c == FLOAT_REGS)
2330 reg_size = UNITS_PER_FP_WORD;
2333 reg_size = UNITS_PER_WORD;
2335 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2336 rs6000_class_max_nregs[m][c]
2337 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2340 if (TARGET_E500_DOUBLE)
2341 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2343 /* Calculate which modes to automatically generate code to use a the
2344 reciprocal divide and square root instructions. In the future, possibly
2345 automatically generate the instructions even if the user did not specify
2346 -mrecip. The older machines double precision reciprocal sqrt estimate is
2347 not accurate enough. */
2348 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2350 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2352 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2353 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2354 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2355 if (VECTOR_UNIT_VSX_P (V2DFmode))
2356 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2358 if (TARGET_FRSQRTES)
2359 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2361 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2362 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2363 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2364 if (VECTOR_UNIT_VSX_P (V2DFmode))
2365 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2367 if (rs6000_recip_control)
2369 if (!flag_finite_math_only)
2370 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2371 if (flag_trapping_math)
2372 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2373 if (!flag_reciprocal_math)
2374 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2375 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2377 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2378 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2379 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2381 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2382 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2383 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2385 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2386 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2387 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2389 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2390 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2391 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2393 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2394 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2395 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2397 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2398 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2399 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2401 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2402 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2403 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2405 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2406 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2407 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2411 if (global_init_p || TARGET_DEBUG_TARGET)
2413 if (TARGET_DEBUG_REG)
2414 rs6000_debug_reg_global ();
2416 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2418 "SImode variable mult cost = %d\n"
2419 "SImode constant mult cost = %d\n"
2420 "SImode short constant mult cost = %d\n"
2421 "DImode multipliciation cost = %d\n"
2422 "SImode division cost = %d\n"
2423 "DImode division cost = %d\n"
2424 "Simple fp operation cost = %d\n"
2425 "DFmode multiplication cost = %d\n"
2426 "SFmode division cost = %d\n"
2427 "DFmode division cost = %d\n"
2428 "cache line size = %d\n"
2429 "l1 cache size = %d\n"
2430 "l2 cache size = %d\n"
2431 "simultaneous prefetches = %d\n"
2434 rs6000_cost->mulsi_const,
2435 rs6000_cost->mulsi_const9,
2443 rs6000_cost->cache_line_size,
2444 rs6000_cost->l1_cache_size,
2445 rs6000_cost->l2_cache_size,
2446 rs6000_cost->simultaneous_prefetches);
2451 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2454 darwin_rs6000_override_options (void)
2456 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2458 rs6000_altivec_abi = 1;
2459 TARGET_ALTIVEC_VRSAVE = 1;
2461 if (DEFAULT_ABI == ABI_DARWIN
2463 darwin_one_byte_bool = 1;
2465 if (TARGET_64BIT && ! TARGET_POWERPC64)
2467 target_flags |= MASK_POWERPC64;
2468 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2472 rs6000_default_long_calls = 1;
2473 target_flags |= MASK_SOFT_FLOAT;
2476 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2478 if (!flag_mkernel && !flag_apple_kext
2480 && ! (target_flags_explicit & MASK_ALTIVEC))
2481 target_flags |= MASK_ALTIVEC;
2483 /* Unless the user (not the configurer) has explicitly overridden
2484 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2485 G4 unless targetting the kernel. */
2488 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2489 && ! (target_flags_explicit & MASK_ALTIVEC)
2490 && ! global_options_set.x_rs6000_cpu_index)
2492 target_flags |= MASK_ALTIVEC;
2497 /* If not otherwise specified by a target, make 'long double' equivalent to
2500 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2501 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2504 /* Override command line options. Mostly we process the processor type and
2505 sometimes adjust other TARGET_ options. */
2508 rs6000_option_override_internal (bool global_init_p)
2511 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2515 struct cl_target_option *main_target_opt
2516 = ((global_init_p || target_option_default_node == NULL)
2517 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2519 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2520 library functions, so warn about it. The flag may be useful for
2521 performance studies from time to time though, so don't disable it
2523 if (global_options_set.x_rs6000_alignment_flags
2524 && rs6000_alignment_flags == MASK_ALIGN_POWER
2525 && DEFAULT_ABI == ABI_DARWIN
2527 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2528 " it is incompatible with the installed C and C++ libraries");
2530 if (global_options_set.x_rs6000_spe_abi
2533 error ("not configured for SPE ABI");
2535 /* Numerous experiment shows that IRA based loop pressure
2536 calculation works better for RTL loop invariant motion on targets
2537 with enough (>= 32) registers. It is an expensive optimization.
2538 So it is on only for peak performance. */
2539 if (optimize >= 3 && global_init_p)
2540 flag_ira_loop_pressure = 1;
2542 /* Set the pointer size. */
2545 rs6000_pmode = (int)DImode;
2546 rs6000_pointer_size = 64;
2550 rs6000_pmode = (int)SImode;
2551 rs6000_pointer_size = 32;
2554 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2555 #ifdef OS_MISSING_POWERPC64
2556 if (OS_MISSING_POWERPC64)
2557 set_masks &= ~MASK_POWERPC64;
2559 #ifdef OS_MISSING_ALTIVEC
2560 if (OS_MISSING_ALTIVEC)
2561 set_masks &= ~MASK_ALTIVEC;
2564 /* Don't override by the processor default if given explicitly. */
2565 set_masks &= ~target_flags_explicit;
2567 /* Identify the processor type. */
2570 if (TARGET_POWERPC64)
2571 default_cpu = "powerpc64";
2572 else if (TARGET_POWERPC)
2573 default_cpu = "powerpc";
2576 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2577 the cpu in a target attribute or pragma, but did not specify a tuning
2578 option, use the cpu for the tuning option rather than the option specified
2579 with -mtune on the command line. */
2580 if (rs6000_cpu_index > 0)
2581 cpu_index = rs6000_cpu_index;
2582 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2583 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2585 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2587 if (rs6000_tune_index > 0)
2588 tune_index = rs6000_tune_index;
2590 rs6000_tune_index = tune_index = cpu_index;
2594 target_flags &= ~set_masks;
2595 target_flags |= (processor_target_table[cpu_index].target_enable
2599 rs6000_cpu = ((tune_index >= 0)
2600 ? processor_target_table[tune_index].processor
2602 ? PROCESSOR_DEFAULT64
2603 : PROCESSOR_DEFAULT));
2605 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2606 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2609 error ("AltiVec not supported in this target");
2611 error ("SPE not supported in this target");
2614 /* Disable Cell microcode if we are optimizing for the Cell
2615 and not optimizing for size. */
2616 if (rs6000_gen_cell_microcode == -1)
2617 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2620 /* If we are optimizing big endian systems for space and it's OK to
2621 use instructions that would be microcoded on the Cell, use the
2622 load/store multiple and string instructions. */
2623 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2624 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2626 /* Don't allow -mmultiple or -mstring on little endian systems
2627 unless the cpu is a 750, because the hardware doesn't support the
2628 instructions used in little endian mode, and causes an alignment
2629 trap. The 750 does not cause an alignment trap (except when the
2630 target is unaligned). */
2632 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2634 if (TARGET_MULTIPLE)
2636 target_flags &= ~MASK_MULTIPLE;
2637 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2638 warning (0, "-mmultiple is not supported on little endian systems");
2643 target_flags &= ~MASK_STRING;
2644 if ((target_flags_explicit & MASK_STRING) != 0)
2645 warning (0, "-mstring is not supported on little endian systems");
2649 /* Add some warnings for VSX. */
2652 const char *msg = NULL;
2653 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2654 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2656 if (target_flags_explicit & MASK_VSX)
2657 msg = N_("-mvsx requires hardware floating point");
2659 target_flags &= ~ MASK_VSX;
2661 else if (TARGET_PAIRED_FLOAT)
2662 msg = N_("-mvsx and -mpaired are incompatible");
2663 /* The hardware will allow VSX and little endian, but until we make sure
2664 things like vector select, etc. work don't allow VSX on little endian
2665 systems at this point. */
2666 else if (!BYTES_BIG_ENDIAN)
2667 msg = N_("-mvsx used with little endian code");
2668 else if (TARGET_AVOID_XFORM > 0)
2669 msg = N_("-mvsx needs indexed addressing");
2670 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2672 if (target_flags_explicit & MASK_VSX)
2673 msg = N_("-mvsx and -mno-altivec are incompatible");
2675 msg = N_("-mno-altivec disables vsx");
2681 target_flags &= ~ MASK_VSX;
2682 target_flags_explicit |= MASK_VSX;
2686 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2687 unless the user explicitly used the -mno-<option> to disable the code. */
2689 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2690 else if (TARGET_POPCNTD)
2691 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2692 else if (TARGET_DFP)
2693 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2694 else if (TARGET_CMPB)
2695 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2696 else if (TARGET_FPRND)
2697 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2698 else if (TARGET_POPCNTB)
2699 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2700 else if (TARGET_ALTIVEC)
2701 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2703 /* E500mc does "better" if we inline more aggressively. Respect the
2704 user's opinion, though. */
2705 if (rs6000_block_move_inline_limit == 0
2706 && (rs6000_cpu == PROCESSOR_PPCE500MC
2707 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2708 rs6000_block_move_inline_limit = 128;
2710 /* store_one_arg depends on expand_block_move to handle at least the
2711 size of reg_parm_stack_space. */
2712 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2713 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2717 /* If the appropriate debug option is enabled, replace the target hooks
2718 with debug versions that call the real version and then prints
2719 debugging information. */
2720 if (TARGET_DEBUG_COST)
2722 targetm.rtx_costs = rs6000_debug_rtx_costs;
2723 targetm.address_cost = rs6000_debug_address_cost;
2724 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2727 if (TARGET_DEBUG_ADDR)
2729 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2730 targetm.legitimize_address = rs6000_debug_legitimize_address;
2731 rs6000_secondary_reload_class_ptr
2732 = rs6000_debug_secondary_reload_class;
2733 rs6000_secondary_memory_needed_ptr
2734 = rs6000_debug_secondary_memory_needed;
2735 rs6000_cannot_change_mode_class_ptr
2736 = rs6000_debug_cannot_change_mode_class;
2737 rs6000_preferred_reload_class_ptr
2738 = rs6000_debug_preferred_reload_class;
2739 rs6000_legitimize_reload_address_ptr
2740 = rs6000_debug_legitimize_reload_address;
2741 rs6000_mode_dependent_address_ptr
2742 = rs6000_debug_mode_dependent_address;
2745 if (rs6000_veclibabi_name)
2747 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2748 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2751 error ("unknown vectorization library ABI type (%s) for "
2752 "-mveclibabi= switch", rs6000_veclibabi_name);
2758 if (!global_options_set.x_rs6000_long_double_type_size)
2760 if (main_target_opt != NULL
2761 && (main_target_opt->x_rs6000_long_double_type_size
2762 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2763 error ("target attribute or pragma changes long double size");
2765 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2768 #ifndef POWERPC_LINUX
2769 if (!global_options_set.x_rs6000_ieeequad)
2770 rs6000_ieeequad = 1;
2773 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2774 target attribute or pragma which automatically enables both options,
2775 unless the altivec ABI was set. This is set by default for 64-bit, but
2777 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2778 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2780 /* Enable Altivec ABI for AIX -maltivec. */
2781 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2783 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2784 error ("target attribute or pragma changes AltiVec ABI");
2786 rs6000_altivec_abi = 1;
2789 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2790 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2791 be explicitly overridden in either case. */
2794 if (!global_options_set.x_rs6000_altivec_abi
2795 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2797 if (main_target_opt != NULL &&
2798 !main_target_opt->x_rs6000_altivec_abi)
2799 error ("target attribute or pragma changes AltiVec ABI");
2801 rs6000_altivec_abi = 1;
2804 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2805 if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
2806 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2809 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2810 So far, the only darwin64 targets are also MACH-O. */
2812 && DEFAULT_ABI == ABI_DARWIN
2815 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2816 error ("target attribute or pragma changes darwin64 ABI");
2819 rs6000_darwin64_abi = 1;
2820 /* Default to natural alignment, for better performance. */
2821 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2825 /* Place FP constants in the constant pool instead of TOC
2826 if section anchors enabled. */
2827 if (flag_section_anchors)
2828 TARGET_NO_FP_IN_TOC = 1;
2830 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2831 SUBTARGET_OVERRIDE_OPTIONS;
2833 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2834 SUBSUBTARGET_OVERRIDE_OPTIONS;
2836 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2837 SUB3TARGET_OVERRIDE_OPTIONS;
2840 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2841 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2843 /* The e500 and e500mc do not have string instructions, and we set
2844 MASK_STRING above when optimizing for size. */
2845 if ((target_flags & MASK_STRING) != 0)
2846 target_flags = target_flags & ~MASK_STRING;
2848 else if (global_options_set.x_rs6000_cpu_index)
2850 /* For the powerpc-eabispe configuration, we set all these by
2851 default, so let's unset them if we manually set another
2852 CPU that is not the E500. */
2853 if (main_target_opt != NULL
2854 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2855 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2856 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2857 error ("target attribute or pragma changes SPE ABI");
2860 if (!global_options_set.x_rs6000_spe_abi)
2862 if (!global_options_set.x_rs6000_spe)
2864 if (!global_options_set.x_rs6000_float_gprs)
2865 rs6000_float_gprs = 0;
2867 if (!(target_flags_explicit & MASK_ISEL))
2868 target_flags &= ~MASK_ISEL;
2871 /* Detect invalid option combinations with E500. */
2874 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2875 && rs6000_cpu != PROCESSOR_POWER5
2876 && rs6000_cpu != PROCESSOR_POWER6
2877 && rs6000_cpu != PROCESSOR_POWER7
2878 && rs6000_cpu != PROCESSOR_PPCA2
2879 && rs6000_cpu != PROCESSOR_CELL);
2880 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2881 || rs6000_cpu == PROCESSOR_POWER5
2882 || rs6000_cpu == PROCESSOR_POWER7);
2883 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2884 || rs6000_cpu == PROCESSOR_POWER5
2885 || rs6000_cpu == PROCESSOR_POWER6
2886 || rs6000_cpu == PROCESSOR_POWER7
2887 || rs6000_cpu == PROCESSOR_PPCE500MC
2888 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2890 /* Allow debug switches to override the above settings. These are set to -1
2891 in rs6000.opt to indicate the user hasn't directly set the switch. */
2892 if (TARGET_ALWAYS_HINT >= 0)
2893 rs6000_always_hint = TARGET_ALWAYS_HINT;
2895 if (TARGET_SCHED_GROUPS >= 0)
2896 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2898 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
2899 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2901 rs6000_sched_restricted_insns_priority
2902 = (rs6000_sched_groups ? 1 : 0);
2904 /* Handle -msched-costly-dep option. */
2905 rs6000_sched_costly_dep
2906 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2908 if (rs6000_sched_costly_dep_str)
2910 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2911 rs6000_sched_costly_dep = no_dep_costly;
2912 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2913 rs6000_sched_costly_dep = all_deps_costly;
2914 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2915 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2916 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2917 rs6000_sched_costly_dep = store_to_load_dep_costly;
2919 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2920 atoi (rs6000_sched_costly_dep_str));
2923 /* Handle -minsert-sched-nops option. */
2924 rs6000_sched_insert_nops
2925 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2927 if (rs6000_sched_insert_nops_str)
2929 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2930 rs6000_sched_insert_nops = sched_finish_none;
2931 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2932 rs6000_sched_insert_nops = sched_finish_pad_groups;
2933 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2934 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2936 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2937 atoi (rs6000_sched_insert_nops_str));
2942 #ifdef TARGET_REGNAMES
2943 /* If the user desires alternate register names, copy in the
2944 alternate names now. */
2945 if (TARGET_REGNAMES)
2946 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2949 /* Set aix_struct_return last, after the ABI is determined.
2950 If -maix-struct-return or -msvr4-struct-return was explicitly
2951 used, don't override with the ABI default. */
2952 if (!global_options_set.x_aix_struct_return)
2953 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2956 /* IBM XL compiler defaults to unsigned bitfields. */
2957 if (TARGET_XL_COMPAT)
2958 flag_signed_bitfields = 0;
2961 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2962 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2965 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2967 /* We can only guarantee the availability of DI pseudo-ops when
2968 assembling for 64-bit targets. */
2971 targetm.asm_out.aligned_op.di = NULL;
2972 targetm.asm_out.unaligned_op.di = NULL;
2976 /* Set branch target alignment, if not optimizing for size. */
2979 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2980 aligned 8byte to avoid misprediction by the branch predictor. */
2981 if (rs6000_cpu == PROCESSOR_TITAN
2982 || rs6000_cpu == PROCESSOR_CELL)
2984 if (align_functions <= 0)
2985 align_functions = 8;
2986 if (align_jumps <= 0)
2988 if (align_loops <= 0)
2991 if (rs6000_align_branch_targets)
2993 if (align_functions <= 0)
2994 align_functions = 16;
2995 if (align_jumps <= 0)
2997 if (align_loops <= 0)
2999 can_override_loop_align = 1;
3003 if (align_jumps_max_skip <= 0)
3004 align_jumps_max_skip = 15;
3005 if (align_loops_max_skip <= 0)
3006 align_loops_max_skip = 15;
3009 /* Arrange to save and restore machine status around nested functions. */
3010 init_machine_status = rs6000_init_machine_status;
3012 /* We should always be splitting complex arguments, but we can't break
3013 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3014 if (DEFAULT_ABI != ABI_AIX)
3015 targetm.calls.split_complex_arg = NULL;
3018 /* Initialize rs6000_cost with the appropriate target costs. */
3020 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3024 case PROCESSOR_RIOS1:
3025 rs6000_cost = &rios1_cost;
3028 case PROCESSOR_RIOS2:
3029 rs6000_cost = &rios2_cost;
3032 case PROCESSOR_RS64A:
3033 rs6000_cost = &rs64a_cost;
3036 case PROCESSOR_MPCCORE:
3037 rs6000_cost = &mpccore_cost;
3040 case PROCESSOR_PPC403:
3041 rs6000_cost = &ppc403_cost;
3044 case PROCESSOR_PPC405:
3045 rs6000_cost = &ppc405_cost;
3048 case PROCESSOR_PPC440:
3049 rs6000_cost = &ppc440_cost;
3052 case PROCESSOR_PPC476:
3053 rs6000_cost = &ppc476_cost;
3056 case PROCESSOR_PPC601:
3057 rs6000_cost = &ppc601_cost;
3060 case PROCESSOR_PPC603:
3061 rs6000_cost = &ppc603_cost;
3064 case PROCESSOR_PPC604:
3065 rs6000_cost = &ppc604_cost;
3068 case PROCESSOR_PPC604e:
3069 rs6000_cost = &ppc604e_cost;
3072 case PROCESSOR_PPC620:
3073 rs6000_cost = &ppc620_cost;
3076 case PROCESSOR_PPC630:
3077 rs6000_cost = &ppc630_cost;
3080 case PROCESSOR_CELL:
3081 rs6000_cost = &ppccell_cost;
3084 case PROCESSOR_PPC750:
3085 case PROCESSOR_PPC7400:
3086 rs6000_cost = &ppc750_cost;
3089 case PROCESSOR_PPC7450:
3090 rs6000_cost = &ppc7450_cost;
3093 case PROCESSOR_PPC8540:
3094 rs6000_cost = &ppc8540_cost;
3097 case PROCESSOR_PPCE300C2:
3098 case PROCESSOR_PPCE300C3:
3099 rs6000_cost = &ppce300c2c3_cost;
3102 case PROCESSOR_PPCE500MC:
3103 rs6000_cost = &ppce500mc_cost;
3106 case PROCESSOR_PPCE500MC64:
3107 rs6000_cost = &ppce500mc64_cost;
3110 case PROCESSOR_TITAN:
3111 rs6000_cost = &titan_cost;
3114 case PROCESSOR_POWER4:
3115 case PROCESSOR_POWER5:
3116 rs6000_cost = &power4_cost;
3119 case PROCESSOR_POWER6:
3120 rs6000_cost = &power6_cost;
3123 case PROCESSOR_POWER7:
3124 rs6000_cost = &power7_cost;
3127 case PROCESSOR_PPCA2:
3128 rs6000_cost = &ppca2_cost;
3137 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3138 rs6000_cost->simultaneous_prefetches,
3139 global_options.x_param_values,
3140 global_options_set.x_param_values);
3141 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3142 global_options.x_param_values,
3143 global_options_set.x_param_values);
3144 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3145 rs6000_cost->cache_line_size,
3146 global_options.x_param_values,
3147 global_options_set.x_param_values);
3148 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3149 global_options.x_param_values,
3150 global_options_set.x_param_values);
3152 /* If using typedef char *va_list, signal that
3153 __builtin_va_start (&ap, 0) can be optimized to
3154 ap = __builtin_next_arg (0). */
3155 if (DEFAULT_ABI != ABI_V4)
3156 targetm.expand_builtin_va_start = NULL;
3159 /* Set up single/double float flags.
3160 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3161 then set both flags. */
3162 if (TARGET_HARD_FLOAT && TARGET_FPRS
3163 && rs6000_single_float == 0 && rs6000_double_float == 0)
3164 rs6000_single_float = rs6000_double_float = 1;
3166 /* Reset single and double FP flags if target is E500. */
3169 rs6000_single_float = rs6000_double_float = 0;
3170 if (TARGET_E500_SINGLE)
3171 rs6000_single_float = 1;
3172 if (TARGET_E500_DOUBLE)
3173 rs6000_single_float = rs6000_double_float = 1;
3176 if (main_target_opt)
3178 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3179 error ("target attribute or pragma changes single precision floating "
3181 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3182 error ("target attribute or pragma changes double precision floating "
3186 /* If not explicitly specified via option, decide whether to generate indexed
3187 load/store instructions. */
3188 if (TARGET_AVOID_XFORM == -1)
3189 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3190 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3191 need indexed accesses and the type used is the scalar type of the element
3192 being loaded or stored. */
3193 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3194 && !TARGET_ALTIVEC);
3196 /* Set the -mrecip options. */
3197 if (rs6000_recip_name)
3199 char *p = ASTRDUP (rs6000_recip_name);
3201 unsigned int mask, i;
3204 while ((q = strtok (p, ",")) != NULL)
3215 if (!strcmp (q, "default"))
3216 mask = ((TARGET_RECIP_PRECISION)
3217 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3220 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3221 if (!strcmp (q, recip_options[i].string))
3223 mask = recip_options[i].mask;
3227 if (i == ARRAY_SIZE (recip_options))
3229 error ("unknown option for -mrecip=%s", q);
3237 rs6000_recip_control &= ~mask;
3239 rs6000_recip_control |= mask;
3243 rs6000_init_hard_regno_mode_ok (global_init_p);
3245 /* Save the initial options in case the user does function specific options */
3247 target_option_default_node = target_option_current_node
3248 = build_target_option_node ();
3253 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3254 define the target cpu type. */
3257 rs6000_option_override (void)
3259 (void) rs6000_option_override_internal (true);
3263 /* Implement targetm.vectorize.builtin_mask_for_load. */
3265 rs6000_builtin_mask_for_load (void)
3267 if (TARGET_ALTIVEC || TARGET_VSX)
3268 return altivec_builtin_mask_for_load;
3273 /* Implement LOOP_ALIGN. */
3275 rs6000_loop_align (rtx label)
3280 /* Don't override loop alignment if -falign-loops was specified. */
3281 if (!can_override_loop_align)
3282 return align_loops_log;
3284 bb = BLOCK_FOR_INSN (label);
3285 ninsns = num_loop_insns(bb->loop_father);
3287 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3288 if (ninsns > 4 && ninsns <= 8
3289 && (rs6000_cpu == PROCESSOR_POWER4
3290 || rs6000_cpu == PROCESSOR_POWER5
3291 || rs6000_cpu == PROCESSOR_POWER6
3292 || rs6000_cpu == PROCESSOR_POWER7))
3295 return align_loops_log;
3298 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3300 rs6000_loop_align_max_skip (rtx label)
3302 return (1 << rs6000_loop_align (label)) - 1;
3305 /* Implement targetm.vectorize.builtin_conversion.
3306 Returns a decl of a function that implements conversion of an integer vector
3307 into a floating-point vector, or vice-versa. DEST_TYPE is the
3308 destination type and SRC_TYPE the source type of the conversion.
3309 Return NULL_TREE if it is not available. */
3311 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3313 enum tree_code code = (enum tree_code) tcode;
3317 case FIX_TRUNC_EXPR:
3318 switch (TYPE_MODE (dest_type))
3321 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3324 return TYPE_UNSIGNED (dest_type)
3325 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3326 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3329 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3332 return TYPE_UNSIGNED (dest_type)
3333 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3334 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3341 switch (TYPE_MODE (src_type))
3344 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3347 return TYPE_UNSIGNED (src_type)
3348 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3349 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3352 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3355 return TYPE_UNSIGNED (src_type)
3356 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3357 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3368 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3370 rs6000_builtin_mul_widen_even (tree type)
3372 if (!TARGET_ALTIVEC)
3375 switch (TYPE_MODE (type))
3378 return TYPE_UNSIGNED (type)
3379 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3380 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3383 return TYPE_UNSIGNED (type)
3384 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3385 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3391 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3393 rs6000_builtin_mul_widen_odd (tree type)
3395 if (!TARGET_ALTIVEC)
3398 switch (TYPE_MODE (type))
3401 return TYPE_UNSIGNED (type)
3402 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3403 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3406 return TYPE_UNSIGNED (type)
3407 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3408 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3415 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3416 after applying N number of iterations. This routine does not determine
3417 how may iterations are required to reach desired alignment. */
3420 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3427 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3430 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3440 /* Assuming that all other types are naturally aligned. CHECKME! */
3445 /* Return true if the vector misalignment factor is supported by the
3448 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3455 /* Return if movmisalign pattern is not supported for this mode. */
3456 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3459 if (misalignment == -1)
3461 /* Misalignment factor is unknown at compile time but we know
3462 it's word aligned. */
3463 if (rs6000_vector_alignment_reachable (type, is_packed))
3465 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3467 if (element_size == 64 || element_size == 32)
3474 /* VSX supports word-aligned vector. */
3475 if (misalignment % 4 == 0)
3481 /* Implement targetm.vectorize.builtin_vec_perm. */
3483 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3485 tree inner_type = TREE_TYPE (type);
3486 bool uns_p = TYPE_UNSIGNED (inner_type);
3489 *mask_element_type = unsigned_char_type_node;
3491 switch (TYPE_MODE (type))
3495 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3496 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3501 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3502 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3507 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3508 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3512 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3516 if (!TARGET_ALLOW_DF_PERMUTE)
3519 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3523 if (!TARGET_ALLOW_DF_PERMUTE)
3527 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3528 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3540 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3542 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3543 tree vectype, int misalign)
3547 switch (type_of_cost)
3557 case cond_branch_not_taken:
3561 case cond_branch_taken:
3564 case unaligned_load:
3565 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3567 elements = TYPE_VECTOR_SUBPARTS (vectype);
3569 /* Double word aligned. */
3577 /* Double word aligned. */
3581 /* Unknown misalignment. */
3594 /* Misaligned loads are not supported. */
3599 case unaligned_store:
3600 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3602 elements = TYPE_VECTOR_SUBPARTS (vectype);
3604 /* Double word aligned. */
3612 /* Double word aligned. */
3616 /* Unknown misalignment. */
3629 /* Misaligned stores are not supported. */
3639 /* Implement targetm.vectorize.preferred_simd_mode. */
3641 static enum machine_mode
3642 rs6000_preferred_simd_mode (enum machine_mode mode)
3651 if (TARGET_ALTIVEC || TARGET_VSX)
3675 if (TARGET_PAIRED_FLOAT
3681 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3684 rs6000_option_default_params (void)
3686 /* Double growth factor to counter reduced min jump length. */
3687 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3690 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3691 library with vectorized intrinsics. */
3694 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3697 const char *suffix = NULL;
3698 tree fntype, new_fndecl, bdecl = NULL_TREE;
3701 enum machine_mode el_mode, in_mode;
3704 /* Libmass is suitable for unsafe math only as it does not correctly support
3705 parts of IEEE with the required precision such as denormals. Only support
3706 it if we have VSX to use the simd d2 or f4 functions.
3707 XXX: Add variable length support. */
3708 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3711 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3712 n = TYPE_VECTOR_SUBPARTS (type_out);
3713 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3714 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3715 if (el_mode != in_mode
3719 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3721 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3724 case BUILT_IN_ATAN2:
3725 case BUILT_IN_HYPOT:
3731 case BUILT_IN_ACOSH:
3733 case BUILT_IN_ASINH:
3735 case BUILT_IN_ATANH:
3743 case BUILT_IN_EXPM1:
3744 case BUILT_IN_LGAMMA:
3745 case BUILT_IN_LOG10:
3746 case BUILT_IN_LOG1P:
3754 bdecl = implicit_built_in_decls[fn];
3755 suffix = "d2"; /* pow -> powd2 */
3756 if (el_mode != DFmode
3761 case BUILT_IN_ATAN2F:
3762 case BUILT_IN_HYPOTF:
3767 case BUILT_IN_ACOSF:
3768 case BUILT_IN_ACOSHF:
3769 case BUILT_IN_ASINF:
3770 case BUILT_IN_ASINHF:
3771 case BUILT_IN_ATANF:
3772 case BUILT_IN_ATANHF:
3773 case BUILT_IN_CBRTF:
3775 case BUILT_IN_COSHF:
3777 case BUILT_IN_ERFCF:
3778 case BUILT_IN_EXP2F:
3780 case BUILT_IN_EXPM1F:
3781 case BUILT_IN_LGAMMAF:
3782 case BUILT_IN_LOG10F:
3783 case BUILT_IN_LOG1PF:
3784 case BUILT_IN_LOG2F:
3787 case BUILT_IN_SINHF:
3788 case BUILT_IN_SQRTF:
3790 case BUILT_IN_TANHF:
3791 bdecl = implicit_built_in_decls[fn];
3792 suffix = "4"; /* powf -> powf4 */
3793 if (el_mode != SFmode
3805 gcc_assert (suffix != NULL);
3806 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3807 strcpy (name, bname + sizeof ("__builtin_") - 1);
3808 strcat (name, suffix);
3811 fntype = build_function_type_list (type_out, type_in, NULL);
3812 else if (n_args == 2)
3813 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3817 /* Build a function declaration for the vectorized function. */
3818 new_fndecl = build_decl (BUILTINS_LOCATION,
3819 FUNCTION_DECL, get_identifier (name), fntype);
3820 TREE_PUBLIC (new_fndecl) = 1;
3821 DECL_EXTERNAL (new_fndecl) = 1;
3822 DECL_IS_NOVOPS (new_fndecl) = 1;
3823 TREE_READONLY (new_fndecl) = 1;
3828 /* Returns a function decl for a vectorized version of the builtin function
3829 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3830 if it is not available. */
3833 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3836 enum machine_mode in_mode, out_mode;
3839 if (TREE_CODE (type_out) != VECTOR_TYPE
3840 || TREE_CODE (type_in) != VECTOR_TYPE
3841 || !TARGET_VECTORIZE_BUILTINS)
3844 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3845 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3846 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3847 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3849 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3851 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3854 case BUILT_IN_COPYSIGN:
3855 if (VECTOR_UNIT_VSX_P (V2DFmode)
3856 && out_mode == DFmode && out_n == 2
3857 && in_mode == DFmode && in_n == 2)
3858 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3860 case BUILT_IN_COPYSIGNF:
3861 if (out_mode != SFmode || out_n != 4
3862 || in_mode != SFmode || in_n != 4)
3864 if (VECTOR_UNIT_VSX_P (V4SFmode))
3865 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3866 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3867 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3870 if (VECTOR_UNIT_VSX_P (V2DFmode)
3871 && out_mode == DFmode && out_n == 2
3872 && in_mode == DFmode && in_n == 2)
3873 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3875 case BUILT_IN_SQRTF:
3876 if (VECTOR_UNIT_VSX_P (V4SFmode)
3877 && out_mode == SFmode && out_n == 4
3878 && in_mode == SFmode && in_n == 4)
3879 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3882 if (VECTOR_UNIT_VSX_P (V2DFmode)
3883 && out_mode == DFmode && out_n == 2
3884 && in_mode == DFmode && in_n == 2)
3885 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3887 case BUILT_IN_CEILF:
3888 if (out_mode != SFmode || out_n != 4
3889 || in_mode != SFmode || in_n != 4)
3891 if (VECTOR_UNIT_VSX_P (V4SFmode))
3892 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3893 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3894 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3896 case BUILT_IN_FLOOR:
3897 if (VECTOR_UNIT_VSX_P (V2DFmode)
3898 && out_mode == DFmode && out_n == 2
3899 && in_mode == DFmode && in_n == 2)
3900 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3902 case BUILT_IN_FLOORF:
3903 if (out_mode != SFmode || out_n != 4
3904 || in_mode != SFmode || in_n != 4)
3906 if (VECTOR_UNIT_VSX_P (V4SFmode))
3907 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3908 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3909 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3912 if (VECTOR_UNIT_VSX_P (V2DFmode)
3913 && out_mode == DFmode && out_n == 2
3914 && in_mode == DFmode && in_n == 2)
3915 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3918 if (VECTOR_UNIT_VSX_P (V4SFmode)
3919 && out_mode == SFmode && out_n == 4
3920 && in_mode == SFmode && in_n == 4)
3921 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3922 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3923 && out_mode == SFmode && out_n == 4
3924 && in_mode == SFmode && in_n == 4)
3925 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3927 case BUILT_IN_TRUNC:
3928 if (VECTOR_UNIT_VSX_P (V2DFmode)
3929 && out_mode == DFmode && out_n == 2
3930 && in_mode == DFmode && in_n == 2)
3931 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3933 case BUILT_IN_TRUNCF:
3934 if (out_mode != SFmode || out_n != 4
3935 || in_mode != SFmode || in_n != 4)
3937 if (VECTOR_UNIT_VSX_P (V4SFmode))
3938 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3939 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3940 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3942 case BUILT_IN_NEARBYINT:
3943 if (VECTOR_UNIT_VSX_P (V2DFmode)
3944 && flag_unsafe_math_optimizations
3945 && out_mode == DFmode && out_n == 2
3946 && in_mode == DFmode && in_n == 2)
3947 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3949 case BUILT_IN_NEARBYINTF:
3950 if (VECTOR_UNIT_VSX_P (V4SFmode)
3951 && flag_unsafe_math_optimizations
3952 && out_mode == SFmode && out_n == 4
3953 && in_mode == SFmode && in_n == 4)
3954 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3957 if (VECTOR_UNIT_VSX_P (V2DFmode)
3958 && !flag_trapping_math
3959 && out_mode == DFmode && out_n == 2
3960 && in_mode == DFmode && in_n == 2)
3961 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3963 case BUILT_IN_RINTF:
3964 if (VECTOR_UNIT_VSX_P (V4SFmode)
3965 && !flag_trapping_math
3966 && out_mode == SFmode && out_n == 4
3967 && in_mode == SFmode && in_n == 4)
3968 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3975 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3977 enum rs6000_builtins fn
3978 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3981 case RS6000_BUILTIN_RSQRTF:
3982 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3983 && out_mode == SFmode && out_n == 4
3984 && in_mode == SFmode && in_n == 4)
3985 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3987 case RS6000_BUILTIN_RSQRT:
3988 if (VECTOR_UNIT_VSX_P (V2DFmode)
3989 && out_mode == DFmode && out_n == 2
3990 && in_mode == DFmode && in_n == 2)
3991 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3993 case RS6000_BUILTIN_RECIPF:
3994 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3995 && out_mode == SFmode && out_n == 4
3996 && in_mode == SFmode && in_n == 4)
3997 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3999 case RS6000_BUILTIN_RECIP:
4000 if (VECTOR_UNIT_VSX_P (V2DFmode)
4001 && out_mode == DFmode && out_n == 2
4002 && in_mode == DFmode && in_n == 2)
4003 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4010 /* Generate calls to libmass if appropriate. */
4011 if (rs6000_veclib_handler)
4012 return rs6000_veclib_handler (fndecl, type_out, type_in);
4017 /* Default CPU string for rs6000*_file_start functions. */
4018 static const char *rs6000_default_cpu;
4020 /* Do anything needed at the start of the asm file. */
4023 rs6000_file_start (void)
4026 const char *start = buffer;
4027 FILE *file = asm_out_file;
4029 rs6000_default_cpu = TARGET_CPU_DEFAULT;
4031 default_file_start ();
4033 #ifdef TARGET_BI_ARCH
4034 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4035 rs6000_default_cpu = 0;
4038 if (flag_verbose_asm)
4040 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4042 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
4044 fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu);
4048 if (global_options_set.x_rs6000_cpu_index)
4050 fprintf (file, "%s -mcpu=%s", start,
4051 processor_target_table[rs6000_cpu_index].name);
4055 if (global_options_set.x_rs6000_tune_index)
4057 fprintf (file, "%s -mtune=%s", start,
4058 processor_target_table[rs6000_tune_index].name);
4062 if (PPC405_ERRATUM77)
4064 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4068 #ifdef USING_ELFOS_H
4069 switch (rs6000_sdata)
4071 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4072 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4073 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4074 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4077 if (rs6000_sdata && g_switch_value)
4079 fprintf (file, "%s -G %d", start,
4089 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4091 switch_to_section (toc_section);
4092 switch_to_section (text_section);
4097 /* Return nonzero if this function is known to have a null epilogue. */
4100 direct_return (void)
4102 if (reload_completed)
4104 rs6000_stack_t *info = rs6000_stack_info ();
4106 if (info->first_gp_reg_save == 32
4107 && info->first_fp_reg_save == 64
4108 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4109 && ! info->lr_save_p
4110 && ! info->cr_save_p
4111 && info->vrsave_mask == 0
4119 /* Return the number of instructions it takes to form a constant in an
4120 integer register. */
4123 num_insns_constant_wide (HOST_WIDE_INT value)
4125 /* signed constant loadable with {cal|addi} */
4126 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4129 /* constant loadable with {cau|addis} */
4130 else if ((value & 0xffff) == 0
4131 && (value >> 31 == -1 || value >> 31 == 0))
4134 #if HOST_BITS_PER_WIDE_INT == 64
4135 else if (TARGET_POWERPC64)
4137 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4138 HOST_WIDE_INT high = value >> 31;
4140 if (high == 0 || high == -1)
4146 return num_insns_constant_wide (high) + 1;
4148 return num_insns_constant_wide (low) + 1;
4150 return (num_insns_constant_wide (high)
4151 + num_insns_constant_wide (low) + 1);
4160 num_insns_constant (rtx op, enum machine_mode mode)
4162 HOST_WIDE_INT low, high;
4164 switch (GET_CODE (op))
4167 #if HOST_BITS_PER_WIDE_INT == 64
4168 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4169 && mask64_operand (op, mode))
4173 return num_insns_constant_wide (INTVAL (op));
4176 if (mode == SFmode || mode == SDmode)
4181 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4182 if (DECIMAL_FLOAT_MODE_P (mode))
4183 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4185 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4186 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4189 if (mode == VOIDmode || mode == DImode)
4191 high = CONST_DOUBLE_HIGH (op);
4192 low = CONST_DOUBLE_LOW (op);
4199 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4200 if (DECIMAL_FLOAT_MODE_P (mode))
4201 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4203 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4204 high = l[WORDS_BIG_ENDIAN == 0];
4205 low = l[WORDS_BIG_ENDIAN != 0];
4209 return (num_insns_constant_wide (low)
4210 + num_insns_constant_wide (high));
4213 if ((high == 0 && low >= 0)
4214 || (high == -1 && low < 0))
4215 return num_insns_constant_wide (low);
4217 else if (mask64_operand (op, mode))
4221 return num_insns_constant_wide (high) + 1;
4224 return (num_insns_constant_wide (high)
4225 + num_insns_constant_wide (low) + 1);
4233 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4234 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4235 corresponding element of the vector, but for V4SFmode and V2SFmode,
4236 the corresponding "float" is interpreted as an SImode integer. */
4239 const_vector_elt_as_int (rtx op, unsigned int elt)
4243 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4244 gcc_assert (GET_MODE (op) != V2DImode
4245 && GET_MODE (op) != V2DFmode);
4247 tmp = CONST_VECTOR_ELT (op, elt);
4248 if (GET_MODE (op) == V4SFmode
4249 || GET_MODE (op) == V2SFmode)
4250 tmp = gen_lowpart (SImode, tmp);
4251 return INTVAL (tmp);
4254 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4255 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4256 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4257 all items are set to the same value and contain COPIES replicas of the
4258 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4259 operand and the others are set to the value of the operand's msb. */
4262 vspltis_constant (rtx op, unsigned step, unsigned copies)
4264 enum machine_mode mode = GET_MODE (op);
4265 enum machine_mode inner = GET_MODE_INNER (mode);
4273 HOST_WIDE_INT splat_val;
4274 HOST_WIDE_INT msb_val;
4276 if (mode == V2DImode || mode == V2DFmode)
4279 nunits = GET_MODE_NUNITS (mode);
4280 bitsize = GET_MODE_BITSIZE (inner);
4281 mask = GET_MODE_MASK (inner);
4283 val = const_vector_elt_as_int (op, nunits - 1);
4285 msb_val = val > 0 ? 0 : -1;
4287 /* Construct the value to be splatted, if possible. If not, return 0. */
4288 for (i = 2; i <= copies; i *= 2)
4290 HOST_WIDE_INT small_val;
4292 small_val = splat_val >> bitsize;
4294 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4296 splat_val = small_val;
4299 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4300 if (EASY_VECTOR_15 (splat_val))
4303 /* Also check if we can splat, and then add the result to itself. Do so if
4304 the value is positive, of if the splat instruction is using OP's mode;
4305 for splat_val < 0, the splat and the add should use the same mode. */
4306 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4307 && (splat_val >= 0 || (step == 1 && copies == 1)))
4310 /* Also check if are loading up the most significant bit which can be done by
4311 loading up -1 and shifting the value left by -1. */
4312 else if (EASY_VECTOR_MSB (splat_val, inner))
4318 /* Check if VAL is present in every STEP-th element, and the
4319 other elements are filled with its most significant bit. */
4320 for (i = 0; i < nunits - 1; ++i)
4322 HOST_WIDE_INT desired_val;
4323 if (((i + 1) & (step - 1)) == 0)
4326 desired_val = msb_val;
4328 if (desired_val != const_vector_elt_as_int (op, i))
4336 /* Return true if OP is of the given MODE and can be synthesized
4337 with a vspltisb, vspltish or vspltisw. */
4340 easy_altivec_constant (rtx op, enum machine_mode mode)
4342 unsigned step, copies;
4344 if (mode == VOIDmode)
4345 mode = GET_MODE (op);
4346 else if (mode != GET_MODE (op))
4349 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4351 if (mode == V2DFmode)
4352 return zero_constant (op, mode);
4354 if (mode == V2DImode)
4356 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4358 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4359 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4362 if (zero_constant (op, mode))
4365 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4366 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4372 /* Start with a vspltisw. */
4373 step = GET_MODE_NUNITS (mode) / 4;
4376 if (vspltis_constant (op, step, copies))
4379 /* Then try with a vspltish. */
4385 if (vspltis_constant (op, step, copies))
4388 /* And finally a vspltisb. */
4394 if (vspltis_constant (op, step, copies))
4400 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4401 result is OP. Abort if it is not possible. */
4404 gen_easy_altivec_constant (rtx op)
4406 enum machine_mode mode = GET_MODE (op);
4407 int nunits = GET_MODE_NUNITS (mode);
4408 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4409 unsigned step = nunits / 4;
4410 unsigned copies = 1;
4412 /* Start with a vspltisw. */
4413 if (vspltis_constant (op, step, copies))
4414 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4416 /* Then try with a vspltish. */
4422 if (vspltis_constant (op, step, copies))
4423 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4425 /* And finally a vspltisb. */
4431 if (vspltis_constant (op, step, copies))
4432 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4438 output_vec_const_move (rtx *operands)
4441 enum machine_mode mode;
4446 mode = GET_MODE (dest);
4450 if (zero_constant (vec, mode))
4451 return "xxlxor %x0,%x0,%x0";
4453 if (mode == V2DImode
4454 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
4455 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
4456 return "vspltisw %0,-1";
4462 if (zero_constant (vec, mode))
4463 return "vxor %0,%0,%0";
4465 splat_vec = gen_easy_altivec_constant (vec);
4466 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4467 operands[1] = XEXP (splat_vec, 0);
4468 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4471 switch (GET_MODE (splat_vec))
4474 return "vspltisw %0,%1";
4477 return "vspltish %0,%1";
4480 return "vspltisb %0,%1";
4487 gcc_assert (TARGET_SPE);
4489 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4490 pattern of V1DI, V4HI, and V2SF.
4492 FIXME: We should probably return # and add post reload
4493 splitters for these, but this way is so easy ;-). */
4494 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4495 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4496 operands[1] = CONST_VECTOR_ELT (vec, 0);
4497 operands[2] = CONST_VECTOR_ELT (vec, 1);
4499 return "li %0,%1\n\tevmergelo %0,%0,%0";
4501 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4504 /* Initialize TARGET of vector PAIRED to VALS. */
4507 paired_expand_vector_init (rtx target, rtx vals)
4509 enum machine_mode mode = GET_MODE (target);
4510 int n_elts = GET_MODE_NUNITS (mode);
4512 rtx x, new_rtx, tmp, constant_op, op1, op2;
4515 for (i = 0; i < n_elts; ++i)
4517 x = XVECEXP (vals, 0, i);
4518 if (!CONSTANT_P (x))
4523 /* Load from constant pool. */
4524 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4530 /* The vector is initialized only with non-constants. */
4531 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4532 XVECEXP (vals, 0, 1));
4534 emit_move_insn (target, new_rtx);
4538 /* One field is non-constant and the other one is a constant. Load the
4539 constant from the constant pool and use ps_merge instruction to
4540 construct the whole vector. */
4541 op1 = XVECEXP (vals, 0, 0);
4542 op2 = XVECEXP (vals, 0, 1);
4544 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4546 tmp = gen_reg_rtx (GET_MODE (constant_op));
4547 emit_move_insn (tmp, constant_op);
4549 if (CONSTANT_P (op1))
4550 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4552 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4554 emit_move_insn (target, new_rtx);
4558 paired_expand_vector_move (rtx operands[])
4560 rtx op0 = operands[0], op1 = operands[1];
4562 emit_move_insn (op0, op1);
4565 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4566 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4567 operands for the relation operation COND. This is a recursive
4571 paired_emit_vector_compare (enum rtx_code rcode,
4572 rtx dest, rtx op0, rtx op1,
4573 rtx cc_op0, rtx cc_op1)
4575 rtx tmp = gen_reg_rtx (V2SFmode);
4578 gcc_assert (TARGET_PAIRED_FLOAT);
4579 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4585 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4589 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4590 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4594 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4597 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4600 tmp1 = gen_reg_rtx (V2SFmode);
4601 max = gen_reg_rtx (V2SFmode);
4602 min = gen_reg_rtx (V2SFmode);
4603 gen_reg_rtx (V2SFmode);
4605 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4606 emit_insn (gen_selv2sf4
4607 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4608 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4609 emit_insn (gen_selv2sf4
4610 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4611 emit_insn (gen_subv2sf3 (tmp1, min, max));
4612 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4615 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4618 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4621 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4624 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4627 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4636 /* Emit vector conditional expression.
4637 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4638 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4641 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4642 rtx cond, rtx cc_op0, rtx cc_op1)
4644 enum rtx_code rcode = GET_CODE (cond);
4646 if (!TARGET_PAIRED_FLOAT)
4649 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4654 /* Initialize vector TARGET to VALS. */
4657 rs6000_expand_vector_init (rtx target, rtx vals)
4659 enum machine_mode mode = GET_MODE (target);
4660 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4661 int n_elts = GET_MODE_NUNITS (mode);
4662 int n_var = 0, one_var = -1;
4663 bool all_same = true, all_const_zero = true;
4667 for (i = 0; i < n_elts; ++i)
4669 x = XVECEXP (vals, 0, i);
4670 if (!CONSTANT_P (x))
4671 ++n_var, one_var = i;
4672 else if (x != CONST0_RTX (inner_mode))
4673 all_const_zero = false;
4675 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4681 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4682 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4683 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4685 /* Zero register. */
4686 emit_insn (gen_rtx_SET (VOIDmode, target,
4687 gen_rtx_XOR (mode, target, target)));
4690 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4692 /* Splat immediate. */
4693 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4698 /* Load from constant pool. */
4699 emit_move_insn (target, const_vec);
4704 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4705 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4709 rtx element = XVECEXP (vals, 0, 0);
4710 if (mode == V2DFmode)
4711 emit_insn (gen_vsx_splat_v2df (target, element));
4713 emit_insn (gen_vsx_splat_v2di (target, element));
4717 if (mode == V2DFmode)
4719 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
4720 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
4721 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4725 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
4726 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
4727 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4733 /* With single precision floating point on VSX, know that internally single
4734 precision is actually represented as a double, and either make 2 V2DF
4735 vectors, and convert these vectors to single precision, or do one
4736 conversion, and splat the result to the other elements. */
4737 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4741 rtx freg = gen_reg_rtx (V4SFmode);
4742 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4744 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4745 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4749 rtx dbl_even = gen_reg_rtx (V2DFmode);
4750 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4751 rtx flt_even = gen_reg_rtx (V4SFmode);
4752 rtx flt_odd = gen_reg_rtx (V4SFmode);
4754 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4755 copy_to_reg (XVECEXP (vals, 0, 0)),
4756 copy_to_reg (XVECEXP (vals, 0, 1))));
4757 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4758 copy_to_reg (XVECEXP (vals, 0, 2)),
4759 copy_to_reg (XVECEXP (vals, 0, 3))));
4760 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4761 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4762 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4767 /* Store value to stack temp. Load vector element. Splat. However, splat
4768 of 64-bit items is not supported on Altivec. */
4769 if (all_same && GET_MODE_SIZE (mode) <= 4)
4771 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4772 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4773 XVECEXP (vals, 0, 0));
4774 x = gen_rtx_UNSPEC (VOIDmode,
4775 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4776 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4778 gen_rtx_SET (VOIDmode,
4781 x = gen_rtx_VEC_SELECT (inner_mode, target,
4782 gen_rtx_PARALLEL (VOIDmode,
4783 gen_rtvec (1, const0_rtx)));
4784 emit_insn (gen_rtx_SET (VOIDmode, target,
4785 gen_rtx_VEC_DUPLICATE (mode, x)));
4789 /* One field is non-constant. Load constant then overwrite
4793 rtx copy = copy_rtx (vals);
4795 /* Load constant part of vector, substitute neighboring value for
4797 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4798 rs6000_expand_vector_init (target, copy);
4800 /* Insert variable. */
4801 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4805 /* Construct the vector in memory one field at a time
4806 and load the whole vector. */
4807 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4808 for (i = 0; i < n_elts; i++)
4809 emit_move_insn (adjust_address_nv (mem, inner_mode,
4810 i * GET_MODE_SIZE (inner_mode)),
4811 XVECEXP (vals, 0, i));
4812 emit_move_insn (target, mem);
4815 /* Set field ELT of TARGET to VAL. */
4818 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4820 enum machine_mode mode = GET_MODE (target);
4821 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4822 rtx reg = gen_reg_rtx (mode);
4824 int width = GET_MODE_SIZE (inner_mode);
4827 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4829 rtx (*set_func) (rtx, rtx, rtx, rtx)
4830 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4831 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4835 /* Load single variable value. */
4836 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4837 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4838 x = gen_rtx_UNSPEC (VOIDmode,
4839 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4840 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4842 gen_rtx_SET (VOIDmode,
4846 /* Linear sequence. */
4847 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4848 for (i = 0; i < 16; ++i)
4849 XVECEXP (mask, 0, i) = GEN_INT (i);
4851 /* Set permute mask to insert element into target. */
4852 for (i = 0; i < width; ++i)
4853 XVECEXP (mask, 0, elt*width + i)
4854 = GEN_INT (i + 0x10);
4855 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4856 x = gen_rtx_UNSPEC (mode,
4857 gen_rtvec (3, target, reg,
4858 force_reg (V16QImode, x)),
4860 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4863 /* Extract field ELT from VEC into TARGET. */
4866 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4868 enum machine_mode mode = GET_MODE (vec);
4869 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4872 if (VECTOR_MEM_VSX_P (mode))
4879 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
4882 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
4885 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
4890 /* Allocate mode-sized buffer. */
4891 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4893 emit_move_insn (mem, vec);
4895 /* Add offset to field within buffer matching vector element. */
4896 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
4898 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4901 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4902 implement ANDing by the mask IN. */
4904 build_mask64_2_operands (rtx in, rtx *out)
4906 #if HOST_BITS_PER_WIDE_INT >= 64
4907 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4910 gcc_assert (GET_CODE (in) == CONST_INT);
4915 /* Assume c initially something like 0x00fff000000fffff. The idea
4916 is to rotate the word so that the middle ^^^^^^ group of zeros
4917 is at the MS end and can be cleared with an rldicl mask. We then
4918 rotate back and clear off the MS ^^ group of zeros with a
4920 c = ~c; /* c == 0xff000ffffff00000 */
4921 lsb = c & -c; /* lsb == 0x0000000000100000 */
4922 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4923 c = ~c; /* c == 0x00fff000000fffff */
4924 c &= -lsb; /* c == 0x00fff00000000000 */
4925 lsb = c & -c; /* lsb == 0x0000100000000000 */
4926 c = ~c; /* c == 0xff000fffffffffff */
4927 c &= -lsb; /* c == 0xff00000000000000 */
4929 while ((lsb >>= 1) != 0)
4930 shift++; /* shift == 44 on exit from loop */
4931 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4932 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4933 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4937 /* Assume c initially something like 0xff000f0000000000. The idea
4938 is to rotate the word so that the ^^^ middle group of zeros
4939 is at the LS end and can be cleared with an rldicr mask. We then
4940 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4942 lsb = c & -c; /* lsb == 0x0000010000000000 */
4943 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4944 c = ~c; /* c == 0x00fff0ffffffffff */
4945 c &= -lsb; /* c == 0x00fff00000000000 */
4946 lsb = c & -c; /* lsb == 0x0000100000000000 */
4947 c = ~c; /* c == 0xff000fffffffffff */
4948 c &= -lsb; /* c == 0xff00000000000000 */
4950 while ((lsb >>= 1) != 0)
4951 shift++; /* shift == 44 on exit from loop */
4952 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4953 m1 >>= shift; /* m1 == 0x0000000000000fff */
4954 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4957 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4958 masks will be all 1's. We are guaranteed more than one transition. */
4959 out[0] = GEN_INT (64 - shift);
4960 out[1] = GEN_INT (m1);
4961 out[2] = GEN_INT (shift);
4962 out[3] = GEN_INT (m2);
4970 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4973 invalid_e500_subreg (rtx op, enum machine_mode mode)
4975 if (TARGET_E500_DOUBLE)
4977 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4978 subreg:TI and reg:TF. Decimal float modes are like integer
4979 modes (only low part of each register used) for this
4981 if (GET_CODE (op) == SUBREG
4982 && (mode == SImode || mode == DImode || mode == TImode
4983 || mode == DDmode || mode == TDmode)
4984 && REG_P (SUBREG_REG (op))
4985 && (GET_MODE (SUBREG_REG (op)) == DFmode
4986 || GET_MODE (SUBREG_REG (op)) == TFmode))
4989 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4991 if (GET_CODE (op) == SUBREG
4992 && (mode == DFmode || mode == TFmode)
4993 && REG_P (SUBREG_REG (op))
4994 && (GET_MODE (SUBREG_REG (op)) == DImode
4995 || GET_MODE (SUBREG_REG (op)) == TImode
4996 || GET_MODE (SUBREG_REG (op)) == DDmode
4997 || GET_MODE (SUBREG_REG (op)) == TDmode))
5002 && GET_CODE (op) == SUBREG
5004 && REG_P (SUBREG_REG (op))
5005 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5011 /* AIX increases natural record alignment to doubleword if the first
5012 field is an FP double while the FP fields remain word aligned. */
5015 rs6000_special_round_type_align (tree type, unsigned int computed,
5016 unsigned int specified)
5018 unsigned int align = MAX (computed, specified);
5019 tree field = TYPE_FIELDS (type);
5021 /* Skip all non field decls */
5022 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5023 field = DECL_CHAIN (field);
5025 if (field != NULL && field != type)
5027 type = TREE_TYPE (field);
5028 while (TREE_CODE (type) == ARRAY_TYPE)
5029 type = TREE_TYPE (type);
5031 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5032 align = MAX (align, 64);
5038 /* Darwin increases record alignment to the natural alignment of
5042 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5043 unsigned int specified)
5045 unsigned int align = MAX (computed, specified);
5047 if (TYPE_PACKED (type))
5050 /* Find the first field, looking down into aggregates. */
5052 tree field = TYPE_FIELDS (type);
5053 /* Skip all non field decls */
5054 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5055 field = DECL_CHAIN (field);
5058 /* A packed field does not contribute any extra alignment. */
5059 if (DECL_PACKED (field))
5061 type = TREE_TYPE (field);
5062 while (TREE_CODE (type) == ARRAY_TYPE)
5063 type = TREE_TYPE (type);
5064 } while (AGGREGATE_TYPE_P (type));
5066 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5067 align = MAX (align, TYPE_ALIGN (type));
5072 /* Return 1 for an operand in small memory on V.4/eabi. */
5075 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5076 enum machine_mode mode ATTRIBUTE_UNUSED)
5081 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5084 if (DEFAULT_ABI != ABI_V4)
5087 /* Vector and float memory instructions have a limited offset on the
5088 SPE, so using a vector or float variable directly as an operand is
5091 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5094 if (GET_CODE (op) == SYMBOL_REF)
5097 else if (GET_CODE (op) != CONST
5098 || GET_CODE (XEXP (op, 0)) != PLUS
5099 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5100 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5105 rtx sum = XEXP (op, 0);
5106 HOST_WIDE_INT summand;
5108 /* We have to be careful here, because it is the referenced address
5109 that must be 32k from _SDA_BASE_, not just the symbol. */
5110 summand = INTVAL (XEXP (sum, 1));
5111 if (summand < 0 || summand > g_switch_value)
5114 sym_ref = XEXP (sum, 0);
5117 return SYMBOL_REF_SMALL_P (sym_ref);
5123 /* Return true if either operand is a general purpose register. */
5126 gpr_or_gpr_p (rtx op0, rtx op1)
5128 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5129 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5133 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5136 reg_offset_addressing_ok_p (enum machine_mode mode)
5146 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5147 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5155 /* Paired vector modes. Only reg+reg addressing is valid. */
5156 if (TARGET_PAIRED_FLOAT)
5168 virtual_stack_registers_memory_p (rtx op)
5172 if (GET_CODE (op) == REG)
5173 regnum = REGNO (op);
5175 else if (GET_CODE (op) == PLUS
5176 && GET_CODE (XEXP (op, 0)) == REG
5177 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5178 regnum = REGNO (XEXP (op, 0));
5183 return (regnum >= FIRST_VIRTUAL_REGISTER
5184 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5187 /* Return true if memory accesses to OP are known to never straddle
5191 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5192 enum machine_mode mode)
5195 unsigned HOST_WIDE_INT dsize, dalign;
5197 if (GET_CODE (op) != SYMBOL_REF)
5200 decl = SYMBOL_REF_DECL (op);
5203 if (GET_MODE_SIZE (mode) == 0)
5206 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5207 replacing memory addresses with an anchor plus offset. We
5208 could find the decl by rummaging around in the block->objects
5209 VEC for the given offset but that seems like too much work. */
5211 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5212 && SYMBOL_REF_ANCHOR_P (op)
5213 && SYMBOL_REF_BLOCK (op) != NULL)
5215 struct object_block *block = SYMBOL_REF_BLOCK (op);
5216 HOST_WIDE_INT lsb, mask;
5218 /* Given the alignment of the block.. */
5219 dalign = block->alignment;
5220 mask = dalign / BITS_PER_UNIT - 1;
5222 /* ..and the combined offset of the anchor and any offset
5223 to this block object.. */
5224 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5225 lsb = offset & -offset;
5227 /* ..find how many bits of the alignment we know for the
5232 return dalign >= GET_MODE_SIZE (mode);
5237 if (TREE_CODE (decl) == FUNCTION_DECL)
5240 if (!DECL_SIZE_UNIT (decl))
5243 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5246 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5250 dalign = DECL_ALIGN_UNIT (decl);
5251 return dalign >= dsize;
5254 type = TREE_TYPE (decl);
5256 if (TREE_CODE (decl) == STRING_CST)
5257 dsize = TREE_STRING_LENGTH (decl);
5258 else if (TYPE_SIZE_UNIT (type)
5259 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5260 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5266 dalign = TYPE_ALIGN (type);
5267 if (CONSTANT_CLASS_P (decl))
5268 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5270 dalign = DATA_ALIGNMENT (decl, dalign);
5271 dalign /= BITS_PER_UNIT;
5272 return dalign >= dsize;
5276 constant_pool_expr_p (rtx op)
5280 split_const (op, &base, &offset);
5281 return (GET_CODE (base) == SYMBOL_REF
5282 && CONSTANT_POOL_ADDRESS_P (base)
5283 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5286 static rtx tocrel_base, tocrel_offset;
5289 toc_relative_expr_p (rtx op)
5291 if (GET_CODE (op) != CONST)
5294 split_const (op, &tocrel_base, &tocrel_offset);
5295 return (GET_CODE (tocrel_base) == UNSPEC
5296 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5299 /* Return true if X is a constant pool address, and also for cmodel=medium
5300 if X is a toc-relative address known to be offsettable within MODE. */
5303 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5307 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5308 && GET_CODE (XEXP (x, 0)) == REG
5309 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5310 || ((TARGET_MINIMAL_TOC
5311 || TARGET_CMODEL != CMODEL_SMALL)
5312 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5313 && toc_relative_expr_p (XEXP (x, 1))
5314 && (TARGET_CMODEL != CMODEL_MEDIUM
5315 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5317 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5318 INTVAL (tocrel_offset), mode)));
5322 legitimate_small_data_p (enum machine_mode mode, rtx x)
5324 return (DEFAULT_ABI == ABI_V4
5325 && !flag_pic && !TARGET_TOC
5326 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5327 && small_data_operand (x, mode));
5330 /* SPE offset addressing is limited to 5-bits worth of double words. */
5331 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5334 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5336 unsigned HOST_WIDE_INT offset, extra;
5338 if (GET_CODE (x) != PLUS)
5340 if (GET_CODE (XEXP (x, 0)) != REG)
5342 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5344 if (!reg_offset_addressing_ok_p (mode))
5345 return virtual_stack_registers_memory_p (x);
5346 if (legitimate_constant_pool_address_p (x, mode, strict))
5348 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5351 offset = INTVAL (XEXP (x, 1));
5359 /* SPE vector modes. */
5360 return SPE_CONST_OFFSET_OK (offset);
5363 if (TARGET_E500_DOUBLE)
5364 return SPE_CONST_OFFSET_OK (offset);
5366 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5368 if (VECTOR_MEM_VSX_P (DFmode))
5373 /* On e500v2, we may have:
5375 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5377 Which gets addressed with evldd instructions. */
5378 if (TARGET_E500_DOUBLE)
5379 return SPE_CONST_OFFSET_OK (offset);
5381 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5383 else if (offset & 3)
5388 if (TARGET_E500_DOUBLE)
5389 return (SPE_CONST_OFFSET_OK (offset)
5390 && SPE_CONST_OFFSET_OK (offset + 8));
5394 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5396 else if (offset & 3)
5407 return (offset < 0x10000) && (offset + extra < 0x10000);
5411 legitimate_indexed_address_p (rtx x, int strict)
5415 if (GET_CODE (x) != PLUS)
5421 /* Recognize the rtl generated by reload which we know will later be
5422 replaced with proper base and index regs. */
5424 && reload_in_progress
5425 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5429 return (REG_P (op0) && REG_P (op1)
5430 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5431 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5432 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5433 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5437 avoiding_indexed_address_p (enum machine_mode mode)
5439 /* Avoid indexed addressing for modes that have non-indexed
5440 load/store instruction forms. */
5441 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5445 legitimate_indirect_address_p (rtx x, int strict)
5447 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5451 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5453 if (!TARGET_MACHO || !flag_pic
5454 || mode != SImode || GET_CODE (x) != MEM)
5458 if (GET_CODE (x) != LO_SUM)
5460 if (GET_CODE (XEXP (x, 0)) != REG)
5462 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5466 return CONSTANT_P (x);
5470 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5472 if (GET_CODE (x) != LO_SUM)
5474 if (GET_CODE (XEXP (x, 0)) != REG)
5476 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5478 /* Restrict addressing for DI because of our SUBREG hackery. */
5479 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5480 || mode == DDmode || mode == TDmode
5485 if (TARGET_ELF || TARGET_MACHO)
5487 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5491 if (GET_MODE_NUNITS (mode) != 1)
5493 if (GET_MODE_BITSIZE (mode) > 64
5494 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5495 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5496 && (mode == DFmode || mode == DDmode))))
5499 return CONSTANT_P (x);
5506 /* Try machine-dependent ways of modifying an illegitimate address
5507 to be legitimate. If we find one, return the new, valid address.
5508 This is used from only one place: `memory_address' in explow.c.
5510 OLDX is the address as it was before break_out_memory_refs was
5511 called. In some cases it is useful to look at this to decide what
5514 It is always safe for this function to do nothing. It exists to
5515 recognize opportunities to optimize the output.
5517 On RS/6000, first check for the sum of a register with a constant
5518 integer that is out of range. If so, generate code to add the
5519 constant with the low-order 16 bits masked to the register and force
5520 this result into another register (this can be done with `cau').
5521 Then generate an address of REG+(CONST&0xffff), allowing for the
5522 possibility of bit 16 being a one.
5524 Then check for the sum of a register and something not constant, try to
5525 load the other things into a register and return the sum. */
5528 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5529 enum machine_mode mode)
5531 unsigned int extra = 0;
5533 if (!reg_offset_addressing_ok_p (mode))
5535 if (virtual_stack_registers_memory_p (x))
5538 /* In theory we should not be seeing addresses of the form reg+0,
5539 but just in case it is generated, optimize it away. */
5540 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5541 return force_reg (Pmode, XEXP (x, 0));
5543 /* Make sure both operands are registers. */
5544 else if (GET_CODE (x) == PLUS)
5545 return gen_rtx_PLUS (Pmode,
5546 force_reg (Pmode, XEXP (x, 0)),
5547 force_reg (Pmode, XEXP (x, 1)));
5549 return force_reg (Pmode, x);
5551 if (GET_CODE (x) == SYMBOL_REF)
5553 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5555 return rs6000_legitimize_tls_address (x, model);
5565 if (!TARGET_POWERPC64)
5573 extra = TARGET_POWERPC64 ? 8 : 12;
5579 if (GET_CODE (x) == PLUS
5580 && GET_CODE (XEXP (x, 0)) == REG
5581 && GET_CODE (XEXP (x, 1)) == CONST_INT
5582 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5584 && !((TARGET_POWERPC64
5585 && (mode == DImode || mode == TImode)
5586 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5587 || SPE_VECTOR_MODE (mode)
5588 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5589 || mode == DImode || mode == DDmode
5590 || mode == TDmode))))
5592 HOST_WIDE_INT high_int, low_int;
5594 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5595 if (low_int >= 0x8000 - extra)
5597 high_int = INTVAL (XEXP (x, 1)) - low_int;
5598 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5599 GEN_INT (high_int)), 0);
5600 return plus_constant (sum, low_int);
5602 else if (GET_CODE (x) == PLUS
5603 && GET_CODE (XEXP (x, 0)) == REG
5604 && GET_CODE (XEXP (x, 1)) != CONST_INT
5605 && GET_MODE_NUNITS (mode) == 1
5606 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5608 || ((mode != DImode && mode != DFmode && mode != DDmode)
5609 || (TARGET_E500_DOUBLE && mode != DDmode)))
5610 && (TARGET_POWERPC64 || mode != DImode)
5611 && !avoiding_indexed_address_p (mode)
5616 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5617 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5619 else if (SPE_VECTOR_MODE (mode)
5620 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5621 || mode == DDmode || mode == TDmode
5622 || mode == DImode)))
5626 /* We accept [reg + reg] and [reg + OFFSET]. */
5628 if (GET_CODE (x) == PLUS)
5630 rtx op1 = XEXP (x, 0);
5631 rtx op2 = XEXP (x, 1);
5634 op1 = force_reg (Pmode, op1);
5636 if (GET_CODE (op2) != REG
5637 && (GET_CODE (op2) != CONST_INT
5638 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5639 || (GET_MODE_SIZE (mode) > 8
5640 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5641 op2 = force_reg (Pmode, op2);
5643 /* We can't always do [reg + reg] for these, because [reg +
5644 reg + offset] is not a legitimate addressing mode. */
5645 y = gen_rtx_PLUS (Pmode, op1, op2);
5647 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5648 return force_reg (Pmode, y);
5653 return force_reg (Pmode, x);
5659 && GET_CODE (x) != CONST_INT
5660 && GET_CODE (x) != CONST_DOUBLE
5662 && GET_MODE_NUNITS (mode) == 1
5663 && (GET_MODE_BITSIZE (mode) <= 32
5664 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5665 && (mode == DFmode || mode == DDmode))))
5667 rtx reg = gen_reg_rtx (Pmode);
5668 emit_insn (gen_elf_high (reg, x));
5669 return gen_rtx_LO_SUM (Pmode, reg, x);
5671 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5674 && ! MACHO_DYNAMIC_NO_PIC_P
5676 && GET_CODE (x) != CONST_INT
5677 && GET_CODE (x) != CONST_DOUBLE
5679 && GET_MODE_NUNITS (mode) == 1
5680 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5681 || (mode != DFmode && mode != DDmode))
5685 rtx reg = gen_reg_rtx (Pmode);
5686 emit_insn (gen_macho_high (reg, x));
5687 return gen_rtx_LO_SUM (Pmode, reg, x);
5690 && GET_CODE (x) == SYMBOL_REF
5691 && constant_pool_expr_p (x)
5692 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5694 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5695 return create_TOC_reference (x, reg);
5701 /* Debug version of rs6000_legitimize_address. */
5703 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5709 ret = rs6000_legitimize_address (x, oldx, mode);
5710 insns = get_insns ();
5716 "\nrs6000_legitimize_address: mode %s, old code %s, "
5717 "new code %s, modified\n",
5718 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5719 GET_RTX_NAME (GET_CODE (ret)));
5721 fprintf (stderr, "Original address:\n");
5724 fprintf (stderr, "oldx:\n");
5727 fprintf (stderr, "New address:\n");
5732 fprintf (stderr, "Insns added:\n");
5733 debug_rtx_list (insns, 20);
5739 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5740 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5751 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5752 We need to emit DTP-relative relocations. */
5755 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5760 fputs ("\t.long\t", file);
5763 fputs (DOUBLE_INT_ASM_OP, file);
5768 output_addr_const (file, x);
5769 fputs ("@dtprel+0x8000", file);
5772 /* In the name of slightly smaller debug output, and to cater to
5773 general assembler lossage, recognize various UNSPEC sequences
5774 and turn them back into a direct symbol reference. */
5777 rs6000_delegitimize_address (rtx orig_x)
5781 orig_x = delegitimize_mem_from_attrs (orig_x);
5786 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
5787 && GET_CODE (XEXP (x, 1)) == CONST)
5789 rtx offset = NULL_RTX;
5791 y = XEXP (XEXP (x, 1), 0);
5792 if (GET_CODE (y) == PLUS
5793 && GET_MODE (y) == Pmode
5794 && CONST_INT_P (XEXP (y, 1)))
5796 offset = XEXP (y, 1);
5799 if (GET_CODE (y) == UNSPEC
5800 && XINT (y, 1) == UNSPEC_TOCREL
5801 && ((GET_CODE (XEXP (x, 0)) == REG
5802 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5803 || TARGET_MINIMAL_TOC
5804 || TARGET_CMODEL != CMODEL_SMALL))
5805 || (TARGET_CMODEL != CMODEL_SMALL
5806 && GET_CODE (XEXP (x, 0)) == CONST
5807 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
5808 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
5809 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
5810 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
5811 && rtx_equal_p (XEXP (x, 1),
5812 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
5814 y = XVECEXP (y, 0, 0);
5815 if (offset != NULL_RTX)
5816 y = gen_rtx_PLUS (Pmode, y, offset);
5817 if (!MEM_P (orig_x))
5820 return replace_equiv_address_nv (orig_x, y);
5825 && GET_CODE (orig_x) == LO_SUM
5826 && GET_CODE (XEXP (orig_x, 1)) == CONST)
5828 y = XEXP (XEXP (orig_x, 1), 0);
5829 if (GET_CODE (y) == UNSPEC
5830 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5831 return XVECEXP (y, 0, 0);
5837 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5839 static GTY(()) rtx rs6000_tls_symbol;
5841 rs6000_tls_get_addr (void)
5843 if (!rs6000_tls_symbol)
5844 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5846 return rs6000_tls_symbol;
5849 /* Construct the SYMBOL_REF for TLS GOT references. */
5851 static GTY(()) rtx rs6000_got_symbol;
5853 rs6000_got_sym (void)
5855 if (!rs6000_got_symbol)
5857 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5858 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5859 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5862 return rs6000_got_symbol;
5865 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5866 this (thread-local) address. */
5869 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5873 dest = gen_reg_rtx (Pmode);
5874 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5880 tlsreg = gen_rtx_REG (Pmode, 13);
5881 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5885 tlsreg = gen_rtx_REG (Pmode, 2);
5886 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5890 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5894 tmp = gen_reg_rtx (Pmode);
5897 tlsreg = gen_rtx_REG (Pmode, 13);
5898 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5902 tlsreg = gen_rtx_REG (Pmode, 2);
5903 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5907 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5909 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5914 rtx r3, got, tga, tmp1, tmp2, call_insn;
5916 /* We currently use relocations like @got@tlsgd for tls, which
5917 means the linker will handle allocation of tls entries, placing
5918 them in the .got section. So use a pointer to the .got section,
5919 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5920 or to secondary GOT sections used by 32-bit -fPIC. */
5922 got = gen_rtx_REG (Pmode, 2);
5926 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5929 rtx gsym = rs6000_got_sym ();
5930 got = gen_reg_rtx (Pmode);
5932 rs6000_emit_move (got, gsym, Pmode);
5937 tmp1 = gen_reg_rtx (Pmode);
5938 tmp2 = gen_reg_rtx (Pmode);
5939 mem = gen_const_mem (Pmode, tmp1);
5940 lab = gen_label_rtx ();
5941 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5942 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5943 emit_move_insn (tmp2, mem);
5944 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5945 set_unique_reg_note (last, REG_EQUAL, gsym);
5950 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5952 tga = rs6000_tls_get_addr ();
5953 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
5954 1, const0_rtx, Pmode);
5956 r3 = gen_rtx_REG (Pmode, 3);
5957 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5958 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5959 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5960 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5961 else if (DEFAULT_ABI == ABI_V4)
5962 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5965 call_insn = last_call_insn ();
5966 PATTERN (call_insn) = insn;
5967 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5968 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5969 pic_offset_table_rtx);
5971 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5973 tga = rs6000_tls_get_addr ();
5974 tmp1 = gen_reg_rtx (Pmode);
5975 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
5976 1, const0_rtx, Pmode);
5978 r3 = gen_rtx_REG (Pmode, 3);
5979 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5980 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5981 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5982 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5983 else if (DEFAULT_ABI == ABI_V4)
5984 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5987 call_insn = last_call_insn ();
5988 PATTERN (call_insn) = insn;
5989 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5990 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5991 pic_offset_table_rtx);
5993 if (rs6000_tls_size == 16)
5996 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5998 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6000 else if (rs6000_tls_size == 32)
6002 tmp2 = gen_reg_rtx (Pmode);
6004 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6006 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6009 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6011 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6015 tmp2 = gen_reg_rtx (Pmode);
6017 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6019 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6021 insn = gen_rtx_SET (Pmode, dest,
6022 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6028 /* IE, or 64-bit offset LE. */
6029 tmp2 = gen_reg_rtx (Pmode);
6031 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6033 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6036 insn = gen_tls_tls_64 (dest, tmp2, addr);
6038 insn = gen_tls_tls_32 (dest, tmp2, addr);
6046 /* Return 1 if X contains a thread-local symbol. */
6049 rs6000_tls_referenced_p (rtx x)
6051 if (! TARGET_HAVE_TLS)
6054 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6057 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6060 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6062 if (GET_CODE (x) == CONST
6063 && GET_CODE (XEXP (x, 0)) == PLUS
6064 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6067 return rs6000_tls_referenced_p (x);
6070 /* Return 1 if *X is a thread-local symbol. This is the same as
6071 rs6000_tls_symbol_ref except for the type of the unused argument. */
6074 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6076 return RS6000_SYMBOL_REF_TLS_P (*x);
6079 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6080 replace the input X, or the original X if no replacement is called for.
6081 The output parameter *WIN is 1 if the calling macro should goto WIN,
6084 For RS/6000, we wish to handle large displacements off a base
6085 register by splitting the addend across an addiu/addis and the mem insn.
6086 This cuts number of extra insns needed from 3 to 1.
6088 On Darwin, we use this to generate code for floating point constants.
6089 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6090 The Darwin code is inside #if TARGET_MACHO because only then are the
6091 machopic_* functions defined. */
6093 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6094 int opnum, int type,
6095 int ind_levels ATTRIBUTE_UNUSED, int *win)
6097 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6099 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6100 DFmode/DImode MEM. */
6103 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6104 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6105 reg_offset_p = false;
6107 /* We must recognize output that we have already generated ourselves. */
6108 if (GET_CODE (x) == PLUS
6109 && GET_CODE (XEXP (x, 0)) == PLUS
6110 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6111 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6112 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6114 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6115 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6116 opnum, (enum reload_type)type);
6121 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6122 if (GET_CODE (x) == LO_SUM
6123 && GET_CODE (XEXP (x, 0)) == HIGH)
6125 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6126 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6127 opnum, (enum reload_type)type);
6133 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6134 && GET_CODE (x) == LO_SUM
6135 && GET_CODE (XEXP (x, 0)) == PLUS
6136 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6137 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6138 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6139 && machopic_operand_p (XEXP (x, 1)))
6141 /* Result of previous invocation of this function on Darwin
6142 floating point constant. */
6143 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6144 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6145 opnum, (enum reload_type)type);
6151 if (TARGET_CMODEL != CMODEL_SMALL
6152 && GET_CODE (x) == LO_SUM
6153 && GET_CODE (XEXP (x, 0)) == PLUS
6154 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6155 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6156 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6157 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6158 && GET_CODE (XEXP (x, 1)) == CONST
6159 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6160 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6161 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6163 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6164 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6165 opnum, (enum reload_type) type);
6170 /* Force ld/std non-word aligned offset into base register by wrapping
6172 if (GET_CODE (x) == PLUS
6173 && GET_CODE (XEXP (x, 0)) == REG
6174 && REGNO (XEXP (x, 0)) < 32
6175 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6176 && GET_CODE (XEXP (x, 1)) == CONST_INT
6178 && (INTVAL (XEXP (x, 1)) & 3) != 0
6179 && VECTOR_MEM_NONE_P (mode)
6180 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6181 && TARGET_POWERPC64)
6183 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6184 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6185 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6186 opnum, (enum reload_type) type);
6191 if (GET_CODE (x) == PLUS
6192 && GET_CODE (XEXP (x, 0)) == REG
6193 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6194 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6195 && GET_CODE (XEXP (x, 1)) == CONST_INT
6197 && !SPE_VECTOR_MODE (mode)
6198 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6199 || mode == DDmode || mode == TDmode
6201 && VECTOR_MEM_NONE_P (mode))
6203 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6204 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6206 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6208 /* Check for 32-bit overflow. */
6209 if (high + low != val)
6215 /* Reload the high part into a base reg; leave the low part
6216 in the mem directly. */
6218 x = gen_rtx_PLUS (GET_MODE (x),
6219 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6223 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6224 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6225 opnum, (enum reload_type)type);
6230 if (GET_CODE (x) == SYMBOL_REF
6232 && VECTOR_MEM_NONE_P (mode)
6233 && !SPE_VECTOR_MODE (mode)
6235 && DEFAULT_ABI == ABI_DARWIN
6236 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6238 && DEFAULT_ABI == ABI_V4
6241 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6242 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6246 && (mode != DImode || TARGET_POWERPC64)
6247 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6248 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6253 rtx offset = machopic_gen_offset (x);
6254 x = gen_rtx_LO_SUM (GET_MODE (x),
6255 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6256 gen_rtx_HIGH (Pmode, offset)), offset);
6260 x = gen_rtx_LO_SUM (GET_MODE (x),
6261 gen_rtx_HIGH (Pmode, x), x);
6263 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6264 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6265 opnum, (enum reload_type)type);
6270 /* Reload an offset address wrapped by an AND that represents the
6271 masking of the lower bits. Strip the outer AND and let reload
6272 convert the offset address into an indirect address. For VSX,
6273 force reload to create the address with an AND in a separate
6274 register, because we can't guarantee an altivec register will
6276 if (VECTOR_MEM_ALTIVEC_P (mode)
6277 && GET_CODE (x) == AND
6278 && GET_CODE (XEXP (x, 0)) == PLUS
6279 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6280 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6281 && GET_CODE (XEXP (x, 1)) == CONST_INT
6282 && INTVAL (XEXP (x, 1)) == -16)
6291 && GET_CODE (x) == SYMBOL_REF
6292 && constant_pool_expr_p (x)
6293 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6295 x = create_TOC_reference (x, NULL_RTX);
6296 if (TARGET_CMODEL != CMODEL_SMALL)
6297 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6298 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6299 opnum, (enum reload_type) type);
6307 /* Debug version of rs6000_legitimize_reload_address. */
6309 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6310 int opnum, int type,
6311 int ind_levels, int *win)
6313 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6316 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6317 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6318 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6322 fprintf (stderr, "Same address returned\n");
6324 fprintf (stderr, "NULL returned\n");
6327 fprintf (stderr, "New address:\n");
6334 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6335 that is a valid memory address for an instruction.
6336 The MODE argument is the machine mode for the MEM expression
6337 that wants to use this address.
6339 On the RS/6000, there are four valid address: a SYMBOL_REF that
6340 refers to a constant pool entry of an address (or the sum of it
6341 plus a constant), a short (16-bit signed) constant plus a register,
6342 the sum of two registers, or a register indirect, possibly with an
6343 auto-increment. For DFmode, DDmode and DImode with a constant plus
6344 register, we must ensure that both words are addressable or PowerPC64
6345 with offset word aligned.
6347 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6348 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6349 because adjacent memory cells are accessed by adding word-sized offsets
6350 during assembly output. */
6352 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6354 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6356 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6357 if (VECTOR_MEM_ALTIVEC_P (mode)
6358 && GET_CODE (x) == AND
6359 && GET_CODE (XEXP (x, 1)) == CONST_INT
6360 && INTVAL (XEXP (x, 1)) == -16)
6363 if (RS6000_SYMBOL_REF_TLS_P (x))
6365 if (legitimate_indirect_address_p (x, reg_ok_strict))
6367 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6368 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6369 && !SPE_VECTOR_MODE (mode)
6372 /* Restrict addressing for DI because of our SUBREG hackery. */
6373 && !(TARGET_E500_DOUBLE
6374 && (mode == DFmode || mode == DDmode || mode == DImode))
6376 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6378 if (virtual_stack_registers_memory_p (x))
6380 if (reg_offset_p && legitimate_small_data_p (mode, x))
6383 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6385 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6388 && GET_CODE (x) == PLUS
6389 && GET_CODE (XEXP (x, 0)) == REG
6390 && (XEXP (x, 0) == virtual_stack_vars_rtx
6391 || XEXP (x, 0) == arg_pointer_rtx)
6392 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6394 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6399 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6401 || (mode != DFmode && mode != DDmode)
6402 || (TARGET_E500_DOUBLE && mode != DDmode))
6403 && (TARGET_POWERPC64 || mode != DImode)
6404 && !avoiding_indexed_address_p (mode)
6405 && legitimate_indexed_address_p (x, reg_ok_strict))
6407 if (GET_CODE (x) == PRE_MODIFY
6411 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6413 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6414 && (TARGET_POWERPC64 || mode != DImode)
6415 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6416 && !SPE_VECTOR_MODE (mode)
6417 /* Restrict addressing for DI because of our SUBREG hackery. */
6418 && !(TARGET_E500_DOUBLE
6419 && (mode == DFmode || mode == DDmode || mode == DImode))
6421 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6422 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6423 || (!avoiding_indexed_address_p (mode)
6424 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6425 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6427 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6432 /* Debug version of rs6000_legitimate_address_p. */
6434 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6437 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6439 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6440 "strict = %d, code = %s\n",
6441 ret ? "true" : "false",
6442 GET_MODE_NAME (mode),
6444 GET_RTX_NAME (GET_CODE (x)));
6450 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6453 rs6000_mode_dependent_address_p (const_rtx addr)
6455 return rs6000_mode_dependent_address_ptr (addr);
6458 /* Go to LABEL if ADDR (a legitimate address expression)
6459 has an effect that depends on the machine mode it is used for.
6461 On the RS/6000 this is true of all integral offsets (since AltiVec
6462 and VSX modes don't allow them) or is a pre-increment or decrement.
6464 ??? Except that due to conceptual problems in offsettable_address_p
6465 we can't really report the problems of integral offsets. So leave
6466 this assuming that the adjustable offset must be valid for the
6467 sub-words of a TFmode operand, which is what we had before. */
6470 rs6000_mode_dependent_address (const_rtx addr)
6472 switch (GET_CODE (addr))
6475 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6476 is considered a legitimate address before reload, so there
6477 are no offset restrictions in that case. Note that this
6478 condition is safe in strict mode because any address involving
6479 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6480 been rejected as illegitimate. */
6481 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6482 && XEXP (addr, 0) != arg_pointer_rtx
6483 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6485 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6486 return val + 12 + 0x8000 >= 0x10000;
6491 /* Anything in the constant pool is sufficiently aligned that
6492 all bytes have the same high part address. */
6493 return !legitimate_constant_pool_address_p (addr, QImode, false);
6495 /* Auto-increment cases are now treated generically in recog.c. */
6497 return TARGET_UPDATE;
6499 /* AND is only allowed in Altivec loads. */
6510 /* Debug version of rs6000_mode_dependent_address. */
6512 rs6000_debug_mode_dependent_address (const_rtx addr)
6514 bool ret = rs6000_mode_dependent_address (addr);
6516 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6517 ret ? "true" : "false");
6523 /* Implement FIND_BASE_TERM. */
6526 rs6000_find_base_term (rtx op)
6530 split_const (op, &base, &offset);
6531 if (GET_CODE (base) == UNSPEC)
6532 switch (XINT (base, 1))
6535 case UNSPEC_MACHOPIC_OFFSET:
6536 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6537 for aliasing purposes. */
6538 return XVECEXP (base, 0, 0);
6544 /* More elaborate version of recog's offsettable_memref_p predicate
6545 that works around the ??? note of rs6000_mode_dependent_address.
6546 In particular it accepts
6548 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6550 in 32-bit mode, that the recog predicate rejects. */
6553 rs6000_offsettable_memref_p (rtx op)
6558 /* First mimic offsettable_memref_p. */
6559 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6562 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6563 the latter predicate knows nothing about the mode of the memory
6564 reference and, therefore, assumes that it is the largest supported
6565 mode (TFmode). As a consequence, legitimate offsettable memory
6566 references are rejected. rs6000_legitimate_offset_address_p contains
6567 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6568 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6571 /* Change register usage conditional on target flags. */
6573 rs6000_conditional_register_usage (void)
6577 if (TARGET_DEBUG_TARGET)
6578 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6580 /* Set MQ register fixed (already call_used) if not POWER
6581 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6586 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6588 fixed_regs[13] = call_used_regs[13]
6589 = call_really_used_regs[13] = 1;
6591 /* Conditionally disable FPRs. */
6592 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6593 for (i = 32; i < 64; i++)
6594 fixed_regs[i] = call_used_regs[i]
6595 = call_really_used_regs[i] = 1;
6597 /* The TOC register is not killed across calls in a way that is
6598 visible to the compiler. */
6599 if (DEFAULT_ABI == ABI_AIX)
6600 call_really_used_regs[2] = 0;
6602 if (DEFAULT_ABI == ABI_V4
6603 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6605 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6607 if (DEFAULT_ABI == ABI_V4
6608 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6610 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6611 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6612 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6614 if (DEFAULT_ABI == ABI_DARWIN
6615 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6616 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6617 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6618 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6620 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6621 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6622 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6626 global_regs[SPEFSCR_REGNO] = 1;
6627 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6628 registers in prologues and epilogues. We no longer use r14
6629 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6630 pool for link-compatibility with older versions of GCC. Once
6631 "old" code has died out, we can return r14 to the allocation
6634 = call_used_regs[14]
6635 = call_really_used_regs[14] = 1;
6638 if (!TARGET_ALTIVEC && !TARGET_VSX)
6640 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6641 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6642 call_really_used_regs[VRSAVE_REGNO] = 1;
6645 if (TARGET_ALTIVEC || TARGET_VSX)
6646 global_regs[VSCR_REGNO] = 1;
6648 if (TARGET_ALTIVEC_ABI)
6650 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6651 call_used_regs[i] = call_really_used_regs[i] = 1;
6653 /* AIX reserves VR20:31 in non-extended ABI mode. */
6655 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6656 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6660 /* Try to output insns to set TARGET equal to the constant C if it can
6661 be done in less than N insns. Do all computations in MODE.
6662 Returns the place where the output has been placed if it can be
6663 done and the insns have been emitted. If it would take more than N
6664 insns, zero is returned and no insns and emitted. */
6667 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6668 rtx source, int n ATTRIBUTE_UNUSED)
6670 rtx result, insn, set;
6671 HOST_WIDE_INT c0, c1;
6678 dest = gen_reg_rtx (mode);
6679 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6683 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6685 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6686 GEN_INT (INTVAL (source)
6687 & (~ (HOST_WIDE_INT) 0xffff))));
6688 emit_insn (gen_rtx_SET (VOIDmode, dest,
6689 gen_rtx_IOR (SImode, copy_rtx (result),
6690 GEN_INT (INTVAL (source) & 0xffff))));
6695 switch (GET_CODE (source))
6698 c0 = INTVAL (source);
6703 #if HOST_BITS_PER_WIDE_INT >= 64
6704 c0 = CONST_DOUBLE_LOW (source);
6707 c0 = CONST_DOUBLE_LOW (source);
6708 c1 = CONST_DOUBLE_HIGH (source);
6716 result = rs6000_emit_set_long_const (dest, c0, c1);
6723 insn = get_last_insn ();
6724 set = single_set (insn);
6725 if (! CONSTANT_P (SET_SRC (set)))
6726 set_unique_reg_note (insn, REG_EQUAL, source);
6731 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6732 fall back to a straight forward decomposition. We do this to avoid
6733 exponential run times encountered when looking for longer sequences
6734 with rs6000_emit_set_const. */
6736 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6738 if (!TARGET_POWERPC64)
6740 rtx operand1, operand2;
6742 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6744 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6746 emit_move_insn (operand1, GEN_INT (c1));
6747 emit_move_insn (operand2, GEN_INT (c2));
6751 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6754 ud2 = (c1 & 0xffff0000) >> 16;
6755 #if HOST_BITS_PER_WIDE_INT >= 64
6759 ud4 = (c2 & 0xffff0000) >> 16;
6761 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6762 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6765 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6767 emit_move_insn (dest, GEN_INT (ud1));
6770 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6771 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6774 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6777 emit_move_insn (dest, GEN_INT (ud2 << 16));
6779 emit_move_insn (copy_rtx (dest),
6780 gen_rtx_IOR (DImode, copy_rtx (dest),
6783 else if (ud3 == 0 && ud4 == 0)
6785 gcc_assert (ud2 & 0x8000);
6786 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6789 emit_move_insn (copy_rtx (dest),
6790 gen_rtx_IOR (DImode, copy_rtx (dest),
6792 emit_move_insn (copy_rtx (dest),
6793 gen_rtx_ZERO_EXTEND (DImode,
6794 gen_lowpart (SImode,
6797 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6798 || (ud4 == 0 && ! (ud3 & 0x8000)))
6801 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6804 emit_move_insn (dest, GEN_INT (ud3 << 16));
6807 emit_move_insn (copy_rtx (dest),
6808 gen_rtx_IOR (DImode, copy_rtx (dest),
6810 emit_move_insn (copy_rtx (dest),
6811 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6814 emit_move_insn (copy_rtx (dest),
6815 gen_rtx_IOR (DImode, copy_rtx (dest),
6821 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6824 emit_move_insn (dest, GEN_INT (ud4 << 16));
6827 emit_move_insn (copy_rtx (dest),
6828 gen_rtx_IOR (DImode, copy_rtx (dest),
6831 emit_move_insn (copy_rtx (dest),
6832 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6835 emit_move_insn (copy_rtx (dest),
6836 gen_rtx_IOR (DImode, copy_rtx (dest),
6837 GEN_INT (ud2 << 16)));
6839 emit_move_insn (copy_rtx (dest),
6840 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6846 /* Helper for the following. Get rid of [r+r] memory refs
6847 in cases where it won't work (TImode, TFmode, TDmode). */
6850 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6852 if (reload_in_progress)
6855 if (GET_CODE (operands[0]) == MEM
6856 && GET_CODE (XEXP (operands[0], 0)) != REG
6857 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
6858 GET_MODE (operands[0]), false))
6860 = replace_equiv_address (operands[0],
6861 copy_addr_to_reg (XEXP (operands[0], 0)));
6863 if (GET_CODE (operands[1]) == MEM
6864 && GET_CODE (XEXP (operands[1], 0)) != REG
6865 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
6866 GET_MODE (operands[1]), false))
6868 = replace_equiv_address (operands[1],
6869 copy_addr_to_reg (XEXP (operands[1], 0)));
6872 /* Emit a move from SOURCE to DEST in mode MODE. */
6874 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6878 operands[1] = source;
6880 if (TARGET_DEBUG_ADDR)
6883 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6884 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6885 GET_MODE_NAME (mode),
6888 can_create_pseudo_p ());
6890 fprintf (stderr, "source:\n");
6894 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6895 if (GET_CODE (operands[1]) == CONST_DOUBLE
6896 && ! FLOAT_MODE_P (mode)
6897 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6899 /* FIXME. This should never happen. */
6900 /* Since it seems that it does, do the safe thing and convert
6902 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6904 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6905 || FLOAT_MODE_P (mode)
6906 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6907 || CONST_DOUBLE_LOW (operands[1]) < 0)
6908 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6909 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6911 /* Check if GCC is setting up a block move that will end up using FP
6912 registers as temporaries. We must make sure this is acceptable. */
6913 if (GET_CODE (operands[0]) == MEM
6914 && GET_CODE (operands[1]) == MEM
6916 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6917 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6918 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6919 ? 32 : MEM_ALIGN (operands[0])))
6920 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6922 : MEM_ALIGN (operands[1]))))
6923 && ! MEM_VOLATILE_P (operands [0])
6924 && ! MEM_VOLATILE_P (operands [1]))
6926 emit_move_insn (adjust_address (operands[0], SImode, 0),
6927 adjust_address (operands[1], SImode, 0));
6928 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6929 adjust_address (copy_rtx (operands[1]), SImode, 4));
6933 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6934 && !gpc_reg_operand (operands[1], mode))
6935 operands[1] = force_reg (mode, operands[1]);
6937 if (mode == SFmode && ! TARGET_POWERPC
6938 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6939 && GET_CODE (operands[0]) == MEM)
6943 if (reload_in_progress || reload_completed)
6944 regnum = true_regnum (operands[1]);
6945 else if (GET_CODE (operands[1]) == REG)
6946 regnum = REGNO (operands[1]);
6950 /* If operands[1] is a register, on POWER it may have
6951 double-precision data in it, so truncate it to single
6953 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6956 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6957 : gen_reg_rtx (mode));
6958 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6959 operands[1] = newreg;
6963 /* Recognize the case where operand[1] is a reference to thread-local
6964 data and load its address to a register. */
6965 if (rs6000_tls_referenced_p (operands[1]))
6967 enum tls_model model;
6968 rtx tmp = operands[1];
6971 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6973 addend = XEXP (XEXP (tmp, 0), 1);
6974 tmp = XEXP (XEXP (tmp, 0), 0);
6977 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6978 model = SYMBOL_REF_TLS_MODEL (tmp);
6979 gcc_assert (model != 0);
6981 tmp = rs6000_legitimize_tls_address (tmp, model);
6984 tmp = gen_rtx_PLUS (mode, tmp, addend);
6985 tmp = force_operand (tmp, operands[0]);
6990 /* Handle the case where reload calls us with an invalid address. */
6991 if (reload_in_progress && mode == Pmode
6992 && (! general_operand (operands[1], mode)
6993 || ! nonimmediate_operand (operands[0], mode)))
6996 /* 128-bit constant floating-point values on Darwin should really be
6997 loaded as two parts. */
6998 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6999 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7001 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7002 know how to get a DFmode SUBREG of a TFmode. */
7003 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7004 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7005 simplify_gen_subreg (imode, operands[1], mode, 0),
7007 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7008 GET_MODE_SIZE (imode)),
7009 simplify_gen_subreg (imode, operands[1], mode,
7010 GET_MODE_SIZE (imode)),
7015 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7016 cfun->machine->sdmode_stack_slot =
7017 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7019 if (reload_in_progress
7021 && MEM_P (operands[0])
7022 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7023 && REG_P (operands[1]))
7025 if (FP_REGNO_P (REGNO (operands[1])))
7027 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7028 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7029 emit_insn (gen_movsd_store (mem, operands[1]));
7031 else if (INT_REGNO_P (REGNO (operands[1])))
7033 rtx mem = adjust_address_nv (operands[0], mode, 4);
7034 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7035 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7041 if (reload_in_progress
7043 && REG_P (operands[0])
7044 && MEM_P (operands[1])
7045 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7047 if (FP_REGNO_P (REGNO (operands[0])))
7049 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7050 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7051 emit_insn (gen_movsd_load (operands[0], mem));
7053 else if (INT_REGNO_P (REGNO (operands[0])))
7055 rtx mem = adjust_address_nv (operands[1], mode, 4);
7056 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7057 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7064 /* FIXME: In the long term, this switch statement should go away
7065 and be replaced by a sequence of tests based on things like
7071 if (CONSTANT_P (operands[1])
7072 && GET_CODE (operands[1]) != CONST_INT)
7073 operands[1] = force_const_mem (mode, operands[1]);
7078 rs6000_eliminate_indexed_memrefs (operands);
7085 if (CONSTANT_P (operands[1])
7086 && ! easy_fp_constant (operands[1], mode))
7087 operands[1] = force_const_mem (mode, operands[1]);
7100 if (CONSTANT_P (operands[1])
7101 && !easy_vector_constant (operands[1], mode))
7102 operands[1] = force_const_mem (mode, operands[1]);
7107 /* Use default pattern for address of ELF small data */
7110 && DEFAULT_ABI == ABI_V4
7111 && (GET_CODE (operands[1]) == SYMBOL_REF
7112 || GET_CODE (operands[1]) == CONST)
7113 && small_data_operand (operands[1], mode))
7115 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7119 if (DEFAULT_ABI == ABI_V4
7120 && mode == Pmode && mode == SImode
7121 && flag_pic == 1 && got_operand (operands[1], mode))
7123 emit_insn (gen_movsi_got (operands[0], operands[1]));
7127 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7131 && CONSTANT_P (operands[1])
7132 && GET_CODE (operands[1]) != HIGH
7133 && GET_CODE (operands[1]) != CONST_INT)
7135 rtx target = (!can_create_pseudo_p ()
7137 : gen_reg_rtx (mode));
7139 /* If this is a function address on -mcall-aixdesc,
7140 convert it to the address of the descriptor. */
7141 if (DEFAULT_ABI == ABI_AIX
7142 && GET_CODE (operands[1]) == SYMBOL_REF
7143 && XSTR (operands[1], 0)[0] == '.')
7145 const char *name = XSTR (operands[1], 0);
7147 while (*name == '.')
7149 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7150 CONSTANT_POOL_ADDRESS_P (new_ref)
7151 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7152 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7153 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7154 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7155 operands[1] = new_ref;
7158 if (DEFAULT_ABI == ABI_DARWIN)
7161 if (MACHO_DYNAMIC_NO_PIC_P)
7163 /* Take care of any required data indirection. */
7164 operands[1] = rs6000_machopic_legitimize_pic_address (
7165 operands[1], mode, operands[0]);
7166 if (operands[0] != operands[1])
7167 emit_insn (gen_rtx_SET (VOIDmode,
7168 operands[0], operands[1]));
7172 emit_insn (gen_macho_high (target, operands[1]));
7173 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7177 emit_insn (gen_elf_high (target, operands[1]));
7178 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7182 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7183 and we have put it in the TOC, we just need to make a TOC-relative
7186 && GET_CODE (operands[1]) == SYMBOL_REF
7187 && constant_pool_expr_p (operands[1])
7188 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7189 get_pool_mode (operands[1])))
7190 || (TARGET_CMODEL == CMODEL_MEDIUM
7191 && GET_CODE (operands[1]) == SYMBOL_REF
7192 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7193 && SYMBOL_REF_LOCAL_P (operands[1])))
7196 if (TARGET_CMODEL != CMODEL_SMALL)
7198 if (can_create_pseudo_p ())
7199 reg = gen_reg_rtx (Pmode);
7203 operands[1] = create_TOC_reference (operands[1], reg);
7205 else if (mode == Pmode
7206 && CONSTANT_P (operands[1])
7207 && GET_CODE (operands[1]) != HIGH
7208 && !(TARGET_CMODEL != CMODEL_SMALL
7209 && GET_CODE (operands[1]) == CONST
7210 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7211 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7212 && ((GET_CODE (operands[1]) != CONST_INT
7213 && ! easy_fp_constant (operands[1], mode))
7214 || (GET_CODE (operands[1]) == CONST_INT
7215 && (num_insns_constant (operands[1], mode)
7216 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7217 || (GET_CODE (operands[0]) == REG
7218 && FP_REGNO_P (REGNO (operands[0]))))
7219 && ! legitimate_constant_pool_address_p (operands[1], mode,
7221 && ! toc_relative_expr_p (operands[1])
7222 && (TARGET_CMODEL == CMODEL_SMALL
7223 || can_create_pseudo_p ()
7224 || (REG_P (operands[0])
7225 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7229 /* Darwin uses a special PIC legitimizer. */
7230 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7233 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7235 if (operands[0] != operands[1])
7236 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7241 /* If we are to limit the number of things we put in the TOC and
7242 this is a symbol plus a constant we can add in one insn,
7243 just put the symbol in the TOC and add the constant. Don't do
7244 this if reload is in progress. */
7245 if (GET_CODE (operands[1]) == CONST
7246 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7247 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7248 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7249 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7250 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7251 && ! side_effects_p (operands[0]))
7254 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7255 rtx other = XEXP (XEXP (operands[1], 0), 1);
7257 sym = force_reg (mode, sym);
7258 emit_insn (gen_add3_insn (operands[0], sym, other));
7262 operands[1] = force_const_mem (mode, operands[1]);
7265 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7266 && constant_pool_expr_p (XEXP (operands[1], 0))
7267 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7268 get_pool_constant (XEXP (operands[1], 0)),
7269 get_pool_mode (XEXP (operands[1], 0))))
7273 if (TARGET_CMODEL != CMODEL_SMALL)
7275 if (can_create_pseudo_p ())
7276 reg = gen_reg_rtx (Pmode);
7280 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7281 operands[1] = gen_const_mem (mode, tocref);
7282 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7288 rs6000_eliminate_indexed_memrefs (operands);
7292 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7294 gen_rtx_SET (VOIDmode,
7295 operands[0], operands[1]),
7296 gen_rtx_CLOBBER (VOIDmode,
7297 gen_rtx_SCRATCH (SImode)))));
7303 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7306 /* Above, we may have called force_const_mem which may have returned
7307 an invalid address. If we can, fix this up; otherwise, reload will
7308 have to deal with it. */
7309 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7310 operands[1] = validize_mem (operands[1]);
7313 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7316 /* Nonzero if we can use a floating-point register to pass this arg. */
7317 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7318 (SCALAR_FLOAT_MODE_P (MODE) \
7319 && (CUM)->fregno <= FP_ARG_MAX_REG \
7320 && TARGET_HARD_FLOAT && TARGET_FPRS)
7322 /* Nonzero if we can use an AltiVec register to pass this arg. */
7323 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7324 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7325 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7326 && TARGET_ALTIVEC_ABI \
7329 /* Return a nonzero value to say to return the function value in
7330 memory, just as large structures are always returned. TYPE will be
7331 the data type of the value, and FNTYPE will be the type of the
7332 function doing the returning, or @code{NULL} for libcalls.
7334 The AIX ABI for the RS/6000 specifies that all structures are
7335 returned in memory. The Darwin ABI does the same.
7337 For the Darwin 64 Bit ABI, a function result can be returned in
7338 registers or in memory, depending on the size of the return data
7339 type. If it is returned in registers, the value occupies the same
7340 registers as it would if it were the first and only function
7341 argument. Otherwise, the function places its result in memory at
7342 the location pointed to by GPR3.
7344 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7345 but a draft put them in memory, and GCC used to implement the draft
7346 instead of the final standard. Therefore, aix_struct_return
7347 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7348 compatibility can change DRAFT_V4_STRUCT_RET to override the
7349 default, and -m switches get the final word. See
7350 rs6000_option_override_internal for more details.
7352 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7353 long double support is enabled. These values are returned in memory.
7355 int_size_in_bytes returns -1 for variable size objects, which go in
7356 memory always. The cast to unsigned makes -1 > 8. */
7359 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7361 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7363 && rs6000_darwin64_abi
7364 && TREE_CODE (type) == RECORD_TYPE
7365 && int_size_in_bytes (type) > 0)
7367 CUMULATIVE_ARGS valcum;
7371 valcum.fregno = FP_ARG_MIN_REG;
7372 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7373 /* Do a trial code generation as if this were going to be passed
7374 as an argument; if any part goes in memory, we return NULL. */
7375 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7378 /* Otherwise fall through to more conventional ABI rules. */
7381 if (AGGREGATE_TYPE_P (type)
7382 && (aix_struct_return
7383 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7386 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7387 modes only exist for GCC vector types if -maltivec. */
7388 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7389 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7392 /* Return synthetic vectors in memory. */
7393 if (TREE_CODE (type) == VECTOR_TYPE
7394 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7396 static bool warned_for_return_big_vectors = false;
7397 if (!warned_for_return_big_vectors)
7399 warning (0, "GCC vector returned by reference: "
7400 "non-standard ABI extension with no compatibility guarantee");
7401 warned_for_return_big_vectors = true;
7406 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7412 #ifdef HAVE_AS_GNU_ATTRIBUTE
7413 /* Return TRUE if a call to function FNDECL may be one that
7414 potentially affects the function calling ABI of the object file. */
7417 call_ABI_of_interest (tree fndecl)
7419 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7421 struct cgraph_node *c_node;
7423 /* Libcalls are always interesting. */
7424 if (fndecl == NULL_TREE)
7427 /* Any call to an external function is interesting. */
7428 if (DECL_EXTERNAL (fndecl))
7431 /* Interesting functions that we are emitting in this object file. */
7432 c_node = cgraph_get_node (fndecl);
7433 c_node = cgraph_function_or_thunk_node (c_node, NULL);
7434 return !cgraph_only_called_directly_p (c_node);
7440 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7441 for a call to a function whose data type is FNTYPE.
7442 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7444 For incoming args we set the number of arguments in the prototype large
7445 so we never return a PARALLEL. */
7448 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7449 rtx libname ATTRIBUTE_UNUSED, int incoming,
7450 int libcall, int n_named_args,
7451 tree fndecl ATTRIBUTE_UNUSED,
7452 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7454 static CUMULATIVE_ARGS zero_cumulative;
7456 *cum = zero_cumulative;
7458 cum->fregno = FP_ARG_MIN_REG;
7459 cum->vregno = ALTIVEC_ARG_MIN_REG;
7460 cum->prototype = (fntype && prototype_p (fntype));
7461 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7462 ? CALL_LIBCALL : CALL_NORMAL);
7463 cum->sysv_gregno = GP_ARG_MIN_REG;
7464 cum->stdarg = stdarg_p (fntype);
7466 cum->nargs_prototype = 0;
7467 if (incoming || cum->prototype)
7468 cum->nargs_prototype = n_named_args;
7470 /* Check for a longcall attribute. */
7471 if ((!fntype && rs6000_default_long_calls)
7473 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7474 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7475 cum->call_cookie |= CALL_LONG;
7477 if (TARGET_DEBUG_ARG)
7479 fprintf (stderr, "\ninit_cumulative_args:");
7482 tree ret_type = TREE_TYPE (fntype);
7483 fprintf (stderr, " ret code = %s,",
7484 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7487 if (cum->call_cookie & CALL_LONG)
7488 fprintf (stderr, " longcall,");
7490 fprintf (stderr, " proto = %d, nargs = %d\n",
7491 cum->prototype, cum->nargs_prototype);
7494 #ifdef HAVE_AS_GNU_ATTRIBUTE
7495 if (DEFAULT_ABI == ABI_V4)
7497 cum->escapes = call_ABI_of_interest (fndecl);
7504 return_type = TREE_TYPE (fntype);
7505 return_mode = TYPE_MODE (return_type);
7508 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7510 if (return_type != NULL)
7512 if (TREE_CODE (return_type) == RECORD_TYPE
7513 && TYPE_TRANSPARENT_AGGR (return_type))
7515 return_type = TREE_TYPE (first_field (return_type));
7516 return_mode = TYPE_MODE (return_type);
7518 if (AGGREGATE_TYPE_P (return_type)
7519 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7521 rs6000_returns_struct = true;
7523 if (SCALAR_FLOAT_MODE_P (return_mode))
7524 rs6000_passes_float = true;
7525 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7526 || SPE_VECTOR_MODE (return_mode))
7527 rs6000_passes_vector = true;
7534 && TARGET_ALTIVEC_ABI
7535 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7537 error ("cannot return value in vector register because"
7538 " altivec instructions are disabled, use -maltivec"
7543 /* Return true if TYPE must be passed on the stack and not in registers. */
7546 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7548 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7549 return must_pass_in_stack_var_size (mode, type);
7551 return must_pass_in_stack_var_size_or_pad (mode, type);
7554 /* If defined, a C expression which determines whether, and in which
7555 direction, to pad out an argument with extra space. The value
7556 should be of type `enum direction': either `upward' to pad above
7557 the argument, `downward' to pad below, or `none' to inhibit
7560 For the AIX ABI structs are always stored left shifted in their
7564 function_arg_padding (enum machine_mode mode, const_tree type)
7566 #ifndef AGGREGATE_PADDING_FIXED
7567 #define AGGREGATE_PADDING_FIXED 0
7569 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7570 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7573 if (!AGGREGATE_PADDING_FIXED)
7575 /* GCC used to pass structures of the same size as integer types as
7576 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7577 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7578 passed padded downward, except that -mstrict-align further
7579 muddied the water in that multi-component structures of 2 and 4
7580 bytes in size were passed padded upward.
7582 The following arranges for best compatibility with previous
7583 versions of gcc, but removes the -mstrict-align dependency. */
7584 if (BYTES_BIG_ENDIAN)
7586 HOST_WIDE_INT size = 0;
7588 if (mode == BLKmode)
7590 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7591 size = int_size_in_bytes (type);
7594 size = GET_MODE_SIZE (mode);
7596 if (size == 1 || size == 2 || size == 4)
7602 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7604 if (type != 0 && AGGREGATE_TYPE_P (type))
7608 /* Fall back to the default. */
7609 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7612 /* If defined, a C expression that gives the alignment boundary, in bits,
7613 of an argument with the specified mode and type. If it is not defined,
7614 PARM_BOUNDARY is used for all arguments.
7616 V.4 wants long longs and doubles to be double word aligned. Just
7617 testing the mode size is a boneheaded way to do this as it means
7618 that other types such as complex int are also double word aligned.
7619 However, we're stuck with this because changing the ABI might break
7620 existing library interfaces.
7622 Doubleword align SPE vectors.
7623 Quadword align Altivec/VSX vectors.
7624 Quadword align large synthetic vector types. */
7627 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7629 if (DEFAULT_ABI == ABI_V4
7630 && (GET_MODE_SIZE (mode) == 8
7631 || (TARGET_HARD_FLOAT
7633 && (mode == TFmode || mode == TDmode))))
7635 else if (SPE_VECTOR_MODE (mode)
7636 || (type && TREE_CODE (type) == VECTOR_TYPE
7637 && int_size_in_bytes (type) >= 8
7638 && int_size_in_bytes (type) < 16))
7640 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7641 || (type && TREE_CODE (type) == VECTOR_TYPE
7642 && int_size_in_bytes (type) >= 16))
7644 else if (TARGET_MACHO
7645 && rs6000_darwin64_abi
7647 && type && TYPE_ALIGN (type) > 64)
7650 return PARM_BOUNDARY;
7653 /* For a function parm of MODE and TYPE, return the starting word in
7654 the parameter area. NWORDS of the parameter area are already used. */
7657 rs6000_parm_start (enum machine_mode mode, const_tree type,
7658 unsigned int nwords)
7661 unsigned int parm_offset;
7663 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7664 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7665 return nwords + (-(parm_offset + nwords) & align);
7668 /* Compute the size (in words) of a function argument. */
7670 static unsigned long
7671 rs6000_arg_size (enum machine_mode mode, const_tree type)
7675 if (mode != BLKmode)
7676 size = GET_MODE_SIZE (mode);
7678 size = int_size_in_bytes (type);
7681 return (size + 3) >> 2;
7683 return (size + 7) >> 3;
7686 /* Use this to flush pending int fields. */
7689 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7690 HOST_WIDE_INT bitpos, int final)
7692 unsigned int startbit, endbit;
7693 int intregs, intoffset;
7694 enum machine_mode mode;
7696 /* Handle the situations where a float is taking up the first half
7697 of the GPR, and the other half is empty (typically due to
7698 alignment restrictions). We can detect this by a 8-byte-aligned
7699 int field, or by seeing that this is the final flush for this
7700 argument. Count the word and continue on. */
7701 if (cum->floats_in_gpr == 1
7702 && (cum->intoffset % 64 == 0
7703 || (cum->intoffset == -1 && final)))
7706 cum->floats_in_gpr = 0;
7709 if (cum->intoffset == -1)
7712 intoffset = cum->intoffset;
7713 cum->intoffset = -1;
7714 cum->floats_in_gpr = 0;
7716 if (intoffset % BITS_PER_WORD != 0)
7718 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7720 if (mode == BLKmode)
7722 /* We couldn't find an appropriate mode, which happens,
7723 e.g., in packed structs when there are 3 bytes to load.
7724 Back intoffset back to the beginning of the word in this
7726 intoffset = intoffset & -BITS_PER_WORD;
7730 startbit = intoffset & -BITS_PER_WORD;
7731 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7732 intregs = (endbit - startbit) / BITS_PER_WORD;
7733 cum->words += intregs;
7734 /* words should be unsigned. */
7735 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7737 int pad = (endbit/BITS_PER_WORD) - cum->words;
7742 /* The darwin64 ABI calls for us to recurse down through structs,
7743 looking for elements passed in registers. Unfortunately, we have
7744 to track int register count here also because of misalignments
7745 in powerpc alignment mode. */
7748 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7750 HOST_WIDE_INT startbitpos)
7754 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7755 if (TREE_CODE (f) == FIELD_DECL)
7757 HOST_WIDE_INT bitpos = startbitpos;
7758 tree ftype = TREE_TYPE (f);
7759 enum machine_mode mode;
7760 if (ftype == error_mark_node)
7762 mode = TYPE_MODE (ftype);
7764 if (DECL_SIZE (f) != 0
7765 && host_integerp (bit_position (f), 1))
7766 bitpos += int_bit_position (f);
7768 /* ??? FIXME: else assume zero offset. */
7770 if (TREE_CODE (ftype) == RECORD_TYPE)
7771 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7772 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7774 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
7775 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7776 cum->fregno += n_fpregs;
7777 /* Single-precision floats present a special problem for
7778 us, because they are smaller than an 8-byte GPR, and so
7779 the structure-packing rules combined with the standard
7780 varargs behavior mean that we want to pack float/float
7781 and float/int combinations into a single register's
7782 space. This is complicated by the arg advance flushing,
7783 which works on arbitrarily large groups of int-type
7787 if (cum->floats_in_gpr == 1)
7789 /* Two floats in a word; count the word and reset
7792 cum->floats_in_gpr = 0;
7794 else if (bitpos % 64 == 0)
7796 /* A float at the beginning of an 8-byte word;
7797 count it and put off adjusting cum->words until
7798 we see if a arg advance flush is going to do it
7800 cum->floats_in_gpr++;
7804 /* The float is at the end of a word, preceded
7805 by integer fields, so the arg advance flush
7806 just above has already set cum->words and
7807 everything is taken care of. */
7811 cum->words += n_fpregs;
7813 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7815 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7819 else if (cum->intoffset == -1)
7820 cum->intoffset = bitpos;
7824 /* Check for an item that needs to be considered specially under the darwin 64
7825 bit ABI. These are record types where the mode is BLK or the structure is
7828 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7830 return rs6000_darwin64_abi
7831 && ((mode == BLKmode
7832 && TREE_CODE (type) == RECORD_TYPE
7833 && int_size_in_bytes (type) > 0)
7834 || (type && TREE_CODE (type) == RECORD_TYPE
7835 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7838 /* Update the data in CUM to advance over an argument
7839 of mode MODE and data type TYPE.
7840 (TYPE is null for libcalls where that information may not be available.)
7842 Note that for args passed by reference, function_arg will be called
7843 with MODE and TYPE set to that of the pointer to the arg, not the arg
7847 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7848 const_tree type, bool named, int depth)
7850 /* Only tick off an argument if we're not recursing. */
7852 cum->nargs_prototype--;
7854 #ifdef HAVE_AS_GNU_ATTRIBUTE
7855 if (DEFAULT_ABI == ABI_V4
7858 if (SCALAR_FLOAT_MODE_P (mode))
7859 rs6000_passes_float = true;
7860 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
7861 rs6000_passes_vector = true;
7862 else if (SPE_VECTOR_MODE (mode)
7864 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7865 rs6000_passes_vector = true;
7869 if (TARGET_ALTIVEC_ABI
7870 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7871 || (type && TREE_CODE (type) == VECTOR_TYPE
7872 && int_size_in_bytes (type) == 16)))
7876 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7879 if (!TARGET_ALTIVEC)
7880 error ("cannot pass argument in vector register because"
7881 " altivec instructions are disabled, use -maltivec"
7884 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7885 even if it is going to be passed in a vector register.
7886 Darwin does the same for variable-argument functions. */
7887 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7888 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7898 /* Vector parameters must be 16-byte aligned. This places
7899 them at 2 mod 4 in terms of words in 32-bit mode, since
7900 the parameter save area starts at offset 24 from the
7901 stack. In 64-bit mode, they just have to start on an
7902 even word, since the parameter save area is 16-byte
7903 aligned. Space for GPRs is reserved even if the argument
7904 will be passed in memory. */
7906 align = (2 - cum->words) & 3;
7908 align = cum->words & 1;
7909 cum->words += align + rs6000_arg_size (mode, type);
7911 if (TARGET_DEBUG_ARG)
7913 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7915 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7916 cum->nargs_prototype, cum->prototype,
7917 GET_MODE_NAME (mode));
7921 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7923 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7926 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7928 int size = int_size_in_bytes (type);
7929 /* Variable sized types have size == -1 and are
7930 treated as if consisting entirely of ints.
7931 Pad to 16 byte boundary if needed. */
7932 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7933 && (cum->words % 2) != 0)
7935 /* For varargs, we can just go up by the size of the struct. */
7937 cum->words += (size + 7) / 8;
7940 /* It is tempting to say int register count just goes up by
7941 sizeof(type)/8, but this is wrong in a case such as
7942 { int; double; int; } [powerpc alignment]. We have to
7943 grovel through the fields for these too. */
7945 cum->floats_in_gpr = 0;
7946 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7947 rs6000_darwin64_record_arg_advance_flush (cum,
7948 size * BITS_PER_UNIT, 1);
7950 if (TARGET_DEBUG_ARG)
7952 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7953 cum->words, TYPE_ALIGN (type), size);
7955 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7956 cum->nargs_prototype, cum->prototype,
7957 GET_MODE_NAME (mode));
7960 else if (DEFAULT_ABI == ABI_V4)
7962 if (TARGET_HARD_FLOAT && TARGET_FPRS
7963 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7964 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7965 || (mode == TFmode && !TARGET_IEEEQUAD)
7966 || mode == SDmode || mode == DDmode || mode == TDmode))
7968 /* _Decimal128 must use an even/odd register pair. This assumes
7969 that the register number is odd when fregno is odd. */
7970 if (mode == TDmode && (cum->fregno % 2) == 1)
7973 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7974 <= FP_ARG_V4_MAX_REG)
7975 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7978 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7979 if (mode == DFmode || mode == TFmode
7980 || mode == DDmode || mode == TDmode)
7981 cum->words += cum->words & 1;
7982 cum->words += rs6000_arg_size (mode, type);
7987 int n_words = rs6000_arg_size (mode, type);
7988 int gregno = cum->sysv_gregno;
7990 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7991 (r7,r8) or (r9,r10). As does any other 2 word item such
7992 as complex int due to a historical mistake. */
7994 gregno += (1 - gregno) & 1;
7996 /* Multi-reg args are not split between registers and stack. */
7997 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7999 /* Long long and SPE vectors are aligned on the stack.
8000 So are other 2 word items such as complex int due to
8001 a historical mistake. */
8003 cum->words += cum->words & 1;
8004 cum->words += n_words;
8007 /* Note: continuing to accumulate gregno past when we've started
8008 spilling to the stack indicates the fact that we've started
8009 spilling to the stack to expand_builtin_saveregs. */
8010 cum->sysv_gregno = gregno + n_words;
8013 if (TARGET_DEBUG_ARG)
8015 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8016 cum->words, cum->fregno);
8017 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8018 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8019 fprintf (stderr, "mode = %4s, named = %d\n",
8020 GET_MODE_NAME (mode), named);
8025 int n_words = rs6000_arg_size (mode, type);
8026 int start_words = cum->words;
8027 int align_words = rs6000_parm_start (mode, type, start_words);
8029 cum->words = align_words + n_words;
8031 if (SCALAR_FLOAT_MODE_P (mode)
8032 && TARGET_HARD_FLOAT && TARGET_FPRS)
8034 /* _Decimal128 must be passed in an even/odd float register pair.
8035 This assumes that the register number is odd when fregno is
8037 if (mode == TDmode && (cum->fregno % 2) == 1)
8039 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8042 if (TARGET_DEBUG_ARG)
8044 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8045 cum->words, cum->fregno);
8046 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8047 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8048 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8049 named, align_words - start_words, depth);
8055 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
8056 const_tree type, bool named)
8058 rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
8063 spe_build_register_parallel (enum machine_mode mode, int gregno)
8070 r1 = gen_rtx_REG (DImode, gregno);
8071 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8072 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8076 r1 = gen_rtx_REG (DImode, gregno);
8077 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8078 r3 = gen_rtx_REG (DImode, gregno + 2);
8079 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8080 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8083 r1 = gen_rtx_REG (DImode, gregno);
8084 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8085 r3 = gen_rtx_REG (DImode, gregno + 2);
8086 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8087 r5 = gen_rtx_REG (DImode, gregno + 4);
8088 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8089 r7 = gen_rtx_REG (DImode, gregno + 6);
8090 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8091 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8098 /* Determine where to put a SIMD argument on the SPE. */
8100 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8103 int gregno = cum->sysv_gregno;
8105 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8106 are passed and returned in a pair of GPRs for ABI compatibility. */
8107 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8108 || mode == DCmode || mode == TCmode))
8110 int n_words = rs6000_arg_size (mode, type);
8112 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8114 gregno += (1 - gregno) & 1;
8116 /* Multi-reg args are not split between registers and stack. */
8117 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8120 return spe_build_register_parallel (mode, gregno);
8124 int n_words = rs6000_arg_size (mode, type);
8126 /* SPE vectors are put in odd registers. */
8127 if (n_words == 2 && (gregno & 1) == 0)
8130 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8133 enum machine_mode m = SImode;
8135 r1 = gen_rtx_REG (m, gregno);
8136 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8137 r2 = gen_rtx_REG (m, gregno + 1);
8138 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8139 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8146 if (gregno <= GP_ARG_MAX_REG)
8147 return gen_rtx_REG (mode, gregno);
8153 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8154 structure between cum->intoffset and bitpos to integer registers. */
8157 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8158 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8160 enum machine_mode mode;
8162 unsigned int startbit, endbit;
8163 int this_regno, intregs, intoffset;
8166 if (cum->intoffset == -1)
8169 intoffset = cum->intoffset;
8170 cum->intoffset = -1;
8172 /* If this is the trailing part of a word, try to only load that
8173 much into the register. Otherwise load the whole register. Note
8174 that in the latter case we may pick up unwanted bits. It's not a
8175 problem at the moment but may wish to revisit. */
8177 if (intoffset % BITS_PER_WORD != 0)
8179 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8181 if (mode == BLKmode)
8183 /* We couldn't find an appropriate mode, which happens,
8184 e.g., in packed structs when there are 3 bytes to load.
8185 Back intoffset back to the beginning of the word in this
8187 intoffset = intoffset & -BITS_PER_WORD;
8194 startbit = intoffset & -BITS_PER_WORD;
8195 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8196 intregs = (endbit - startbit) / BITS_PER_WORD;
8197 this_regno = cum->words + intoffset / BITS_PER_WORD;
8199 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8202 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8206 intoffset /= BITS_PER_UNIT;
8209 regno = GP_ARG_MIN_REG + this_regno;
8210 reg = gen_rtx_REG (mode, regno);
8212 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8215 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8219 while (intregs > 0);
8222 /* Recursive workhorse for the following. */
8225 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8226 HOST_WIDE_INT startbitpos, rtx rvec[],
8231 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8232 if (TREE_CODE (f) == FIELD_DECL)
8234 HOST_WIDE_INT bitpos = startbitpos;
8235 tree ftype = TREE_TYPE (f);
8236 enum machine_mode mode;
8237 if (ftype == error_mark_node)
8239 mode = TYPE_MODE (ftype);
8241 if (DECL_SIZE (f) != 0
8242 && host_integerp (bit_position (f), 1))
8243 bitpos += int_bit_position (f);
8245 /* ??? FIXME: else assume zero offset. */
8247 if (TREE_CODE (ftype) == RECORD_TYPE)
8248 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8249 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8251 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8255 case SCmode: mode = SFmode; break;
8256 case DCmode: mode = DFmode; break;
8257 case TCmode: mode = TFmode; break;
8261 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8262 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8264 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8265 && (mode == TFmode || mode == TDmode));
8266 /* Long double or _Decimal128 split over regs and memory. */
8267 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8271 = gen_rtx_EXPR_LIST (VOIDmode,
8272 gen_rtx_REG (mode, cum->fregno++),
8273 GEN_INT (bitpos / BITS_PER_UNIT));
8274 if (mode == TFmode || mode == TDmode)
8277 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8279 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8281 = gen_rtx_EXPR_LIST (VOIDmode,
8282 gen_rtx_REG (mode, cum->vregno++),
8283 GEN_INT (bitpos / BITS_PER_UNIT));
8285 else if (cum->intoffset == -1)
8286 cum->intoffset = bitpos;
8290 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8291 the register(s) to be used for each field and subfield of a struct
8292 being passed by value, along with the offset of where the
8293 register's value may be found in the block. FP fields go in FP
8294 register, vector fields go in vector registers, and everything
8295 else goes in int registers, packed as in memory.
8297 This code is also used for function return values. RETVAL indicates
8298 whether this is the case.
8300 Much of this is taken from the SPARC V9 port, which has a similar
8301 calling convention. */
8304 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8305 bool named, bool retval)
8307 rtx rvec[FIRST_PSEUDO_REGISTER];
8308 int k = 1, kbase = 1;
8309 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8310 /* This is a copy; modifications are not visible to our caller. */
8311 CUMULATIVE_ARGS copy_cum = *orig_cum;
8312 CUMULATIVE_ARGS *cum = ©_cum;
8314 /* Pad to 16 byte boundary if needed. */
8315 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8316 && (cum->words % 2) != 0)
8323 /* Put entries into rvec[] for individual FP and vector fields, and
8324 for the chunks of memory that go in int regs. Note we start at
8325 element 1; 0 is reserved for an indication of using memory, and
8326 may or may not be filled in below. */
8327 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8328 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8330 /* If any part of the struct went on the stack put all of it there.
8331 This hack is because the generic code for
8332 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8333 parts of the struct are not at the beginning. */
8337 return NULL_RTX; /* doesn't go in registers at all */
8339 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8341 if (k > 1 || cum->use_stack)
8342 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8347 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8350 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8355 rtx rvec[GP_ARG_NUM_REG + 1];
8357 if (align_words >= GP_ARG_NUM_REG)
8360 n_units = rs6000_arg_size (mode, type);
8362 /* Optimize the simple case where the arg fits in one gpr, except in
8363 the case of BLKmode due to assign_parms assuming that registers are
8364 BITS_PER_WORD wide. */
8366 || (n_units == 1 && mode != BLKmode))
8367 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8370 if (align_words + n_units > GP_ARG_NUM_REG)
8371 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8372 using a magic NULL_RTX component.
8373 This is not strictly correct. Only some of the arg belongs in
8374 memory, not all of it. However, the normal scheme using
8375 function_arg_partial_nregs can result in unusual subregs, eg.
8376 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8377 store the whole arg to memory is often more efficient than code
8378 to store pieces, and we know that space is available in the right
8379 place for the whole arg. */
8380 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8385 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8386 rtx off = GEN_INT (i++ * 4);
8387 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8389 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8391 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8394 /* Determine where to put an argument to a function.
8395 Value is zero to push the argument on the stack,
8396 or a hard register in which to store the argument.
8398 MODE is the argument's machine mode.
8399 TYPE is the data type of the argument (as a tree).
8400 This is null for libcalls where that information may
8402 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8403 the preceding args and about the function being called. It is
8404 not modified in this routine.
8405 NAMED is nonzero if this argument is a named parameter
8406 (otherwise it is an extra parameter matching an ellipsis).
8408 On RS/6000 the first eight words of non-FP are normally in registers
8409 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8410 Under V.4, the first 8 FP args are in registers.
8412 If this is floating-point and no prototype is specified, we use
8413 both an FP and integer register (or possibly FP reg and stack). Library
8414 functions (when CALL_LIBCALL is set) always have the proper types for args,
8415 so we can pass the FP value just in one register. emit_library_function
8416 doesn't support PARALLEL anyway.
8418 Note that for args passed by reference, function_arg will be called
8419 with MODE and TYPE set to that of the pointer to the arg, not the arg
8423 rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
8424 const_tree type, bool named)
8426 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8427 enum rs6000_abi abi = DEFAULT_ABI;
8429 /* Return a marker to indicate whether CR1 needs to set or clear the
8430 bit that V.4 uses to say fp args were passed in registers.
8431 Assume that we don't need the marker for software floating point,
8432 or compiler generated library calls. */
8433 if (mode == VOIDmode)
8436 && (cum->call_cookie & CALL_LIBCALL) == 0
8438 || (cum->nargs_prototype < 0
8439 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8441 /* For the SPE, we need to crxor CR6 always. */
8443 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8444 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8445 return GEN_INT (cum->call_cookie
8446 | ((cum->fregno == FP_ARG_MIN_REG)
8447 ? CALL_V4_SET_FP_ARGS
8448 : CALL_V4_CLEAR_FP_ARGS));
8451 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8454 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8456 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8457 if (rslt != NULL_RTX)
8459 /* Else fall through to usual handling. */
8462 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8463 if (TARGET_64BIT && ! cum->prototype)
8465 /* Vector parameters get passed in vector register
8466 and also in GPRs or memory, in absence of prototype. */
8469 align_words = (cum->words + 1) & ~1;
8471 if (align_words >= GP_ARG_NUM_REG)
8477 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8479 return gen_rtx_PARALLEL (mode,
8481 gen_rtx_EXPR_LIST (VOIDmode,
8483 gen_rtx_EXPR_LIST (VOIDmode,
8484 gen_rtx_REG (mode, cum->vregno),
8488 return gen_rtx_REG (mode, cum->vregno);
8489 else if (TARGET_ALTIVEC_ABI
8490 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8491 || (type && TREE_CODE (type) == VECTOR_TYPE
8492 && int_size_in_bytes (type) == 16)))
8494 if (named || abi == ABI_V4)
8498 /* Vector parameters to varargs functions under AIX or Darwin
8499 get passed in memory and possibly also in GPRs. */
8500 int align, align_words, n_words;
8501 enum machine_mode part_mode;
8503 /* Vector parameters must be 16-byte aligned. This places them at
8504 2 mod 4 in terms of words in 32-bit mode, since the parameter
8505 save area starts at offset 24 from the stack. In 64-bit mode,
8506 they just have to start on an even word, since the parameter
8507 save area is 16-byte aligned. */
8509 align = (2 - cum->words) & 3;
8511 align = cum->words & 1;
8512 align_words = cum->words + align;
8514 /* Out of registers? Memory, then. */
8515 if (align_words >= GP_ARG_NUM_REG)
8518 if (TARGET_32BIT && TARGET_POWERPC64)
8519 return rs6000_mixed_function_arg (mode, type, align_words);
8521 /* The vector value goes in GPRs. Only the part of the
8522 value in GPRs is reported here. */
8524 n_words = rs6000_arg_size (mode, type);
8525 if (align_words + n_words > GP_ARG_NUM_REG)
8526 /* Fortunately, there are only two possibilities, the value
8527 is either wholly in GPRs or half in GPRs and half not. */
8530 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8533 else if (TARGET_SPE_ABI && TARGET_SPE
8534 && (SPE_VECTOR_MODE (mode)
8535 || (TARGET_E500_DOUBLE && (mode == DFmode
8538 || mode == TCmode))))
8539 return rs6000_spe_function_arg (cum, mode, type);
8541 else if (abi == ABI_V4)
8543 if (TARGET_HARD_FLOAT && TARGET_FPRS
8544 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8545 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8546 || (mode == TFmode && !TARGET_IEEEQUAD)
8547 || mode == SDmode || mode == DDmode || mode == TDmode))
8549 /* _Decimal128 must use an even/odd register pair. This assumes
8550 that the register number is odd when fregno is odd. */
8551 if (mode == TDmode && (cum->fregno % 2) == 1)
8554 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8555 <= FP_ARG_V4_MAX_REG)
8556 return gen_rtx_REG (mode, cum->fregno);
8562 int n_words = rs6000_arg_size (mode, type);
8563 int gregno = cum->sysv_gregno;
8565 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8566 (r7,r8) or (r9,r10). As does any other 2 word item such
8567 as complex int due to a historical mistake. */
8569 gregno += (1 - gregno) & 1;
8571 /* Multi-reg args are not split between registers and stack. */
8572 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8575 if (TARGET_32BIT && TARGET_POWERPC64)
8576 return rs6000_mixed_function_arg (mode, type,
8577 gregno - GP_ARG_MIN_REG);
8578 return gen_rtx_REG (mode, gregno);
8583 int align_words = rs6000_parm_start (mode, type, cum->words);
8585 /* _Decimal128 must be passed in an even/odd float register pair.
8586 This assumes that the register number is odd when fregno is odd. */
8587 if (mode == TDmode && (cum->fregno % 2) == 1)
8590 if (USE_FP_FOR_ARG_P (cum, mode, type))
8592 rtx rvec[GP_ARG_NUM_REG + 1];
8596 enum machine_mode fmode = mode;
8597 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8599 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8601 /* Currently, we only ever need one reg here because complex
8602 doubles are split. */
8603 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8604 && (fmode == TFmode || fmode == TDmode));
8606 /* Long double or _Decimal128 split over regs and memory. */
8607 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8610 /* Do we also need to pass this arg in the parameter save
8613 && (cum->nargs_prototype <= 0
8614 || (DEFAULT_ABI == ABI_AIX
8616 && align_words >= GP_ARG_NUM_REG)));
8618 if (!needs_psave && mode == fmode)
8619 return gen_rtx_REG (fmode, cum->fregno);
8624 /* Describe the part that goes in gprs or the stack.
8625 This piece must come first, before the fprs. */
8626 if (align_words < GP_ARG_NUM_REG)
8628 unsigned long n_words = rs6000_arg_size (mode, type);
8630 if (align_words + n_words > GP_ARG_NUM_REG
8631 || (TARGET_32BIT && TARGET_POWERPC64))
8633 /* If this is partially on the stack, then we only
8634 include the portion actually in registers here. */
8635 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8638 if (align_words + n_words > GP_ARG_NUM_REG)
8639 /* Not all of the arg fits in gprs. Say that it
8640 goes in memory too, using a magic NULL_RTX
8641 component. Also see comment in
8642 rs6000_mixed_function_arg for why the normal
8643 function_arg_partial_nregs scheme doesn't work
8645 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8649 r = gen_rtx_REG (rmode,
8650 GP_ARG_MIN_REG + align_words);
8651 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8652 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8654 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8658 /* The whole arg fits in gprs. */
8659 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8660 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8664 /* It's entirely in memory. */
8665 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8668 /* Describe where this piece goes in the fprs. */
8669 r = gen_rtx_REG (fmode, cum->fregno);
8670 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8672 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8674 else if (align_words < GP_ARG_NUM_REG)
8676 if (TARGET_32BIT && TARGET_POWERPC64)
8677 return rs6000_mixed_function_arg (mode, type, align_words);
8679 if (mode == BLKmode)
8682 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8689 /* For an arg passed partly in registers and partly in memory, this is
8690 the number of bytes passed in registers. For args passed entirely in
8691 registers or entirely in memory, zero. When an arg is described by a
8692 PARALLEL, perhaps using more than one register type, this function
8693 returns the number of bytes used by the first element of the PARALLEL. */
8696 rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
8697 tree type, bool named)
8699 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8703 if (DEFAULT_ABI == ABI_V4)
8706 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8707 && cum->nargs_prototype >= 0)
8710 /* In this complicated case we just disable the partial_nregs code. */
8711 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8714 align_words = rs6000_parm_start (mode, type, cum->words);
8716 if (USE_FP_FOR_ARG_P (cum, mode, type))
8718 /* If we are passing this arg in the fixed parameter save area
8719 (gprs or memory) as well as fprs, then this function should
8720 return the number of partial bytes passed in the parameter
8721 save area rather than partial bytes passed in fprs. */
8723 && (cum->nargs_prototype <= 0
8724 || (DEFAULT_ABI == ABI_AIX
8726 && align_words >= GP_ARG_NUM_REG)))
8728 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8729 > FP_ARG_MAX_REG + 1)
8730 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8731 else if (cum->nargs_prototype >= 0)
8735 if (align_words < GP_ARG_NUM_REG
8736 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8737 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8739 if (ret != 0 && TARGET_DEBUG_ARG)
8740 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8745 /* A C expression that indicates when an argument must be passed by
8746 reference. If nonzero for an argument, a copy of that argument is
8747 made in memory and a pointer to the argument is passed instead of
8748 the argument itself. The pointer is passed in whatever way is
8749 appropriate for passing a pointer to that type.
8751 Under V.4, aggregates and long double are passed by reference.
8753 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8754 reference unless the AltiVec vector extension ABI is in force.
8756 As an extension to all ABIs, variable sized types are passed by
8760 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
8761 enum machine_mode mode, const_tree type,
8762 bool named ATTRIBUTE_UNUSED)
8764 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8766 if (TARGET_DEBUG_ARG)
8767 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8774 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8776 if (TARGET_DEBUG_ARG)
8777 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8781 if (int_size_in_bytes (type) < 0)
8783 if (TARGET_DEBUG_ARG)
8784 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8788 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8789 modes only exist for GCC vector types if -maltivec. */
8790 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8792 if (TARGET_DEBUG_ARG)
8793 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8797 /* Pass synthetic vectors in memory. */
8798 if (TREE_CODE (type) == VECTOR_TYPE
8799 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8801 static bool warned_for_pass_big_vectors = false;
8802 if (TARGET_DEBUG_ARG)
8803 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8804 if (!warned_for_pass_big_vectors)
8806 warning (0, "GCC vector passed by reference: "
8807 "non-standard ABI extension with no compatibility guarantee");
8808 warned_for_pass_big_vectors = true;
8817 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8820 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8825 for (i = 0; i < nregs; i++)
8827 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8828 if (reload_completed)
8830 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8833 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8834 i * GET_MODE_SIZE (reg_mode));
8837 tem = replace_equiv_address (tem, XEXP (tem, 0));
8841 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8845 /* Perform any needed actions needed for a function that is receiving a
8846 variable number of arguments.
8850 MODE and TYPE are the mode and type of the current parameter.
8852 PRETEND_SIZE is a variable that should be set to the amount of stack
8853 that must be pushed by the prolog to pretend that our caller pushed
8856 Normally, this macro will push all remaining incoming registers on the
8857 stack and set PRETEND_SIZE to the length of the registers pushed. */
8860 setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
8861 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8864 CUMULATIVE_ARGS next_cum;
8865 int reg_size = TARGET_32BIT ? 4 : 8;
8866 rtx save_area = NULL_RTX, mem;
8867 int first_reg_offset;
8870 /* Skip the last named argument. */
8871 next_cum = *get_cumulative_args (cum);
8872 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8874 if (DEFAULT_ABI == ABI_V4)
8876 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8880 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8881 HOST_WIDE_INT offset = 0;
8883 /* Try to optimize the size of the varargs save area.
8884 The ABI requires that ap.reg_save_area is doubleword
8885 aligned, but we don't need to allocate space for all
8886 the bytes, only those to which we actually will save
8888 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8889 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8890 if (TARGET_HARD_FLOAT && TARGET_FPRS
8891 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8892 && cfun->va_list_fpr_size)
8895 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8896 * UNITS_PER_FP_WORD;
8897 if (cfun->va_list_fpr_size
8898 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8899 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8901 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8902 * UNITS_PER_FP_WORD;
8906 offset = -((first_reg_offset * reg_size) & ~7);
8907 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8909 gpr_reg_num = cfun->va_list_gpr_size;
8910 if (reg_size == 4 && (first_reg_offset & 1))
8913 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8916 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8918 - (int) (GP_ARG_NUM_REG * reg_size);
8920 if (gpr_size + fpr_size)
8923 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8924 gcc_assert (GET_CODE (reg_save_area) == MEM);
8925 reg_save_area = XEXP (reg_save_area, 0);
8926 if (GET_CODE (reg_save_area) == PLUS)
8928 gcc_assert (XEXP (reg_save_area, 0)
8929 == virtual_stack_vars_rtx);
8930 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8931 offset += INTVAL (XEXP (reg_save_area, 1));
8934 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8937 cfun->machine->varargs_save_offset = offset;
8938 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8943 first_reg_offset = next_cum.words;
8944 save_area = virtual_incoming_args_rtx;
8946 if (targetm.calls.must_pass_in_stack (mode, type))
8947 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8950 set = get_varargs_alias_set ();
8951 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8952 && cfun->va_list_gpr_size)
8954 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8956 if (va_list_gpr_counter_field)
8958 /* V4 va_list_gpr_size counts number of registers needed. */
8959 if (nregs > cfun->va_list_gpr_size)
8960 nregs = cfun->va_list_gpr_size;
8964 /* char * va_list instead counts number of bytes needed. */
8965 if (nregs > cfun->va_list_gpr_size / reg_size)
8966 nregs = cfun->va_list_gpr_size / reg_size;
8969 mem = gen_rtx_MEM (BLKmode,
8970 plus_constant (save_area,
8971 first_reg_offset * reg_size));
8972 MEM_NOTRAP_P (mem) = 1;
8973 set_mem_alias_set (mem, set);
8974 set_mem_align (mem, BITS_PER_WORD);
8976 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8980 /* Save FP registers if needed. */
8981 if (DEFAULT_ABI == ABI_V4
8982 && TARGET_HARD_FLOAT && TARGET_FPRS
8984 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8985 && cfun->va_list_fpr_size)
8987 int fregno = next_cum.fregno, nregs;
8988 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8989 rtx lab = gen_label_rtx ();
8990 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8991 * UNITS_PER_FP_WORD);
8994 (gen_rtx_SET (VOIDmode,
8996 gen_rtx_IF_THEN_ELSE (VOIDmode,
8997 gen_rtx_NE (VOIDmode, cr1,
8999 gen_rtx_LABEL_REF (VOIDmode, lab),
9003 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9004 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9006 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9008 plus_constant (save_area, off));
9009 MEM_NOTRAP_P (mem) = 1;
9010 set_mem_alias_set (mem, set);
9011 set_mem_align (mem, GET_MODE_ALIGNMENT (
9012 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9013 ? DFmode : SFmode));
9014 emit_move_insn (mem, gen_rtx_REG (
9015 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9016 ? DFmode : SFmode, fregno));
9023 /* Create the va_list data type. */
9026 rs6000_build_builtin_va_list (void)
9028 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9030 /* For AIX, prefer 'char *' because that's what the system
9031 header files like. */
9032 if (DEFAULT_ABI != ABI_V4)
9033 return build_pointer_type (char_type_node);
9035 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9036 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9037 get_identifier ("__va_list_tag"), record);
9039 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9040 unsigned_char_type_node);
9041 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9042 unsigned_char_type_node);
9043 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9045 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9046 get_identifier ("reserved"), short_unsigned_type_node);
9047 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9048 get_identifier ("overflow_arg_area"),
9050 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9051 get_identifier ("reg_save_area"),
9054 va_list_gpr_counter_field = f_gpr;
9055 va_list_fpr_counter_field = f_fpr;
9057 DECL_FIELD_CONTEXT (f_gpr) = record;
9058 DECL_FIELD_CONTEXT (f_fpr) = record;
9059 DECL_FIELD_CONTEXT (f_res) = record;
9060 DECL_FIELD_CONTEXT (f_ovf) = record;
9061 DECL_FIELD_CONTEXT (f_sav) = record;
9063 TYPE_STUB_DECL (record) = type_decl;
9064 TYPE_NAME (record) = type_decl;
9065 TYPE_FIELDS (record) = f_gpr;
9066 DECL_CHAIN (f_gpr) = f_fpr;
9067 DECL_CHAIN (f_fpr) = f_res;
9068 DECL_CHAIN (f_res) = f_ovf;
9069 DECL_CHAIN (f_ovf) = f_sav;
9071 layout_type (record);
9073 /* The correct type is an array type of one element. */
9074 return build_array_type (record, build_index_type (size_zero_node));
9077 /* Implement va_start. */
9080 rs6000_va_start (tree valist, rtx nextarg)
9082 HOST_WIDE_INT words, n_gpr, n_fpr;
9083 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9084 tree gpr, fpr, ovf, sav, t;
9086 /* Only SVR4 needs something special. */
9087 if (DEFAULT_ABI != ABI_V4)
9089 std_expand_builtin_va_start (valist, nextarg);
9093 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9094 f_fpr = DECL_CHAIN (f_gpr);
9095 f_res = DECL_CHAIN (f_fpr);
9096 f_ovf = DECL_CHAIN (f_res);
9097 f_sav = DECL_CHAIN (f_ovf);
9099 valist = build_simple_mem_ref (valist);
9100 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9101 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9103 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9105 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9108 /* Count number of gp and fp argument registers used. */
9109 words = crtl->args.info.words;
9110 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9112 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9115 if (TARGET_DEBUG_ARG)
9116 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9117 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9118 words, n_gpr, n_fpr);
9120 if (cfun->va_list_gpr_size)
9122 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9123 build_int_cst (NULL_TREE, n_gpr));
9124 TREE_SIDE_EFFECTS (t) = 1;
9125 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9128 if (cfun->va_list_fpr_size)
9130 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9131 build_int_cst (NULL_TREE, n_fpr));
9132 TREE_SIDE_EFFECTS (t) = 1;
9133 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9135 #ifdef HAVE_AS_GNU_ATTRIBUTE
9136 if (call_ABI_of_interest (cfun->decl))
9137 rs6000_passes_float = true;
9141 /* Find the overflow area. */
9142 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9144 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9145 size_int (words * UNITS_PER_WORD));
9146 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9147 TREE_SIDE_EFFECTS (t) = 1;
9148 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9150 /* If there were no va_arg invocations, don't set up the register
9152 if (!cfun->va_list_gpr_size
9153 && !cfun->va_list_fpr_size
9154 && n_gpr < GP_ARG_NUM_REG
9155 && n_fpr < FP_ARG_V4_MAX_REG)
9158 /* Find the register save area. */
9159 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9160 if (cfun->machine->varargs_save_offset)
9161 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9162 size_int (cfun->machine->varargs_save_offset));
9163 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9164 TREE_SIDE_EFFECTS (t) = 1;
9165 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9168 /* Implement va_arg. */
9171 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9174 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9175 tree gpr, fpr, ovf, sav, reg, t, u;
9176 int size, rsize, n_reg, sav_ofs, sav_scale;
9177 tree lab_false, lab_over, addr;
9179 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9183 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9185 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9186 return build_va_arg_indirect_ref (t);
9189 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9190 earlier version of gcc, with the property that it always applied alignment
9191 adjustments to the va-args (even for zero-sized types). The cheapest way
9192 to deal with this is to replicate the effect of the part of
9193 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9195 We don't need to check for pass-by-reference because of the test above.
9196 We can return a simplifed answer, since we know there's no offset to add. */
9199 && rs6000_darwin64_abi
9200 && integer_zerop (TYPE_SIZE (type)))
9202 unsigned HOST_WIDE_INT align, boundary;
9203 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9204 align = PARM_BOUNDARY / BITS_PER_UNIT;
9205 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9206 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9207 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9208 boundary /= BITS_PER_UNIT;
9209 if (boundary > align)
9212 /* This updates arg ptr by the amount that would be necessary
9213 to align the zero-sized (but not zero-alignment) item. */
9214 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9215 fold_build2 (POINTER_PLUS_EXPR,
9217 valist_tmp, size_int (boundary - 1)));
9218 gimplify_and_add (t, pre_p);
9220 t = fold_convert (sizetype, valist_tmp);
9221 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9222 fold_convert (TREE_TYPE (valist),
9223 fold_build2 (BIT_AND_EXPR, sizetype, t,
9224 size_int (-boundary))));
9225 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9226 gimplify_and_add (t, pre_p);
9228 /* Since it is zero-sized there's no increment for the item itself. */
9229 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9230 return build_va_arg_indirect_ref (valist_tmp);
9233 if (DEFAULT_ABI != ABI_V4)
9235 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9237 tree elem_type = TREE_TYPE (type);
9238 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9239 int elem_size = GET_MODE_SIZE (elem_mode);
9241 if (elem_size < UNITS_PER_WORD)
9243 tree real_part, imag_part;
9244 gimple_seq post = NULL;
9246 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9248 /* Copy the value into a temporary, lest the formal temporary
9249 be reused out from under us. */
9250 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9251 gimple_seq_add_seq (pre_p, post);
9253 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9256 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9260 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9263 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9264 f_fpr = DECL_CHAIN (f_gpr);
9265 f_res = DECL_CHAIN (f_fpr);
9266 f_ovf = DECL_CHAIN (f_res);
9267 f_sav = DECL_CHAIN (f_ovf);
9269 valist = build_va_arg_indirect_ref (valist);
9270 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9271 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9273 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9275 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9278 size = int_size_in_bytes (type);
9279 rsize = (size + 3) / 4;
9282 if (TARGET_HARD_FLOAT && TARGET_FPRS
9283 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9284 || (TARGET_DOUBLE_FLOAT
9285 && (TYPE_MODE (type) == DFmode
9286 || TYPE_MODE (type) == TFmode
9287 || TYPE_MODE (type) == SDmode
9288 || TYPE_MODE (type) == DDmode
9289 || TYPE_MODE (type) == TDmode))))
9291 /* FP args go in FP registers, if present. */
9293 n_reg = (size + 7) / 8;
9294 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9295 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9296 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9301 /* Otherwise into GP registers. */
9310 /* Pull the value out of the saved registers.... */
9313 addr = create_tmp_var (ptr_type_node, "addr");
9315 /* AltiVec vectors never go in registers when -mabi=altivec. */
9316 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9320 lab_false = create_artificial_label (input_location);
9321 lab_over = create_artificial_label (input_location);
9323 /* Long long and SPE vectors are aligned in the registers.
9324 As are any other 2 gpr item such as complex int due to a
9325 historical mistake. */
9327 if (n_reg == 2 && reg == gpr)
9330 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9331 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9332 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9333 unshare_expr (reg), u);
9335 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9336 reg number is 0 for f1, so we want to make it odd. */
9337 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9339 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9340 build_int_cst (TREE_TYPE (reg), 1));
9341 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9344 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9345 t = build2 (GE_EXPR, boolean_type_node, u, t);
9346 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9347 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9348 gimplify_and_add (t, pre_p);
9352 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9354 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9355 build_int_cst (TREE_TYPE (reg), n_reg));
9356 u = fold_convert (sizetype, u);
9357 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9358 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9360 /* _Decimal32 varargs are located in the second word of the 64-bit
9361 FP register for 32-bit binaries. */
9362 if (!TARGET_POWERPC64
9363 && TARGET_HARD_FLOAT && TARGET_FPRS
9364 && TYPE_MODE (type) == SDmode)
9365 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9367 gimplify_assign (addr, t, pre_p);
9369 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9371 stmt = gimple_build_label (lab_false);
9372 gimple_seq_add_stmt (pre_p, stmt);
9374 if ((n_reg == 2 && !regalign) || n_reg > 2)
9376 /* Ensure that we don't find any more args in regs.
9377 Alignment has taken care of for special cases. */
9378 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9382 /* ... otherwise out of the overflow area. */
9384 /* Care for on-stack alignment if needed. */
9388 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9389 t = fold_convert (sizetype, t);
9390 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9392 t = fold_convert (TREE_TYPE (ovf), t);
9394 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9396 gimplify_assign (unshare_expr (addr), t, pre_p);
9398 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9399 gimplify_assign (unshare_expr (ovf), t, pre_p);
9403 stmt = gimple_build_label (lab_over);
9404 gimple_seq_add_stmt (pre_p, stmt);
9407 if (STRICT_ALIGNMENT
9408 && (TYPE_ALIGN (type)
9409 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9411 /* The value (of type complex double, for example) may not be
9412 aligned in memory in the saved registers, so copy via a
9413 temporary. (This is the same code as used for SPARC.) */
9414 tree tmp = create_tmp_var (type, "va_arg_tmp");
9415 tree dest_addr = build_fold_addr_expr (tmp);
9417 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9418 3, dest_addr, addr, size_int (rsize * 4));
9420 gimplify_and_add (copy, pre_p);
9424 addr = fold_convert (ptrtype, addr);
9425 return build_va_arg_indirect_ref (addr);
9431 def_builtin (int mask, const char *name, tree type, int code)
9433 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9436 if (rs6000_builtin_decls[code])
9437 fatal_error ("internal error: builtin function to %s already processed",
9440 rs6000_builtin_decls[code] = t =
9441 add_builtin_function (name, type, code, BUILT_IN_MD,
9444 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9445 switch (builtin_classify[code])
9450 /* assume builtin can do anything. */
9451 case RS6000_BTC_MISC:
9454 /* const function, function only depends on the inputs. */
9455 case RS6000_BTC_CONST:
9456 TREE_READONLY (t) = 1;
9457 TREE_NOTHROW (t) = 1;
9460 /* pure function, function can read global memory. */
9461 case RS6000_BTC_PURE:
9462 DECL_PURE_P (t) = 1;
9463 TREE_NOTHROW (t) = 1;
9466 /* Function is a math function. If rounding mode is on, then treat
9467 the function as not reading global memory, but it can have
9468 arbitrary side effects. If it is off, then assume the function is
9469 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9470 attribute in builtin-attribute.def that is used for the math
9472 case RS6000_BTC_FP_PURE:
9473 TREE_NOTHROW (t) = 1;
9474 if (flag_rounding_math)
9476 DECL_PURE_P (t) = 1;
9477 DECL_IS_NOVOPS (t) = 1;
9480 TREE_READONLY (t) = 1;
9486 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9488 static const struct builtin_description bdesc_3arg[] =
9490 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9491 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9492 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9493 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9494 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9495 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9496 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9497 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9498 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9499 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9500 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9501 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9502 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9503 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9504 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9505 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9506 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9507 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9508 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9509 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9510 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9511 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9512 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9513 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9514 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9515 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9516 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9517 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9518 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9519 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9520 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9521 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9522 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9523 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9524 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9542 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9543 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9544 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9545 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9547 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9548 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9549 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9550 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9552 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9553 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9555 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9556 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9557 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9558 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9559 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9560 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9561 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9562 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9563 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9564 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9566 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9567 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9568 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9569 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9570 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9571 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9572 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9573 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9574 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9575 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9577 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9578 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9579 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9580 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9581 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9582 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9583 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9584 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9585 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9587 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9588 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9589 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9590 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9591 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9592 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9593 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9595 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9596 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9597 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9598 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9599 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9600 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9601 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9602 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9603 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9606 /* DST operations: void foo (void *, const int, const char). */
9608 static const struct builtin_description bdesc_dst[] =
9610 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9611 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9612 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9615 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9616 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9617 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9618 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9621 /* Simple binary operations: VECc = foo (VECa, VECb). */
9623 static struct builtin_description bdesc_2arg[] =
9625 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9626 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9627 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9628 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9633 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9634 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9635 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9636 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9637 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9638 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9639 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9640 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9641 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9642 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9643 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9644 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9645 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9646 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9647 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9648 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9649 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9650 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9651 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9652 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9653 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9654 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9655 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9656 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9657 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9658 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9659 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9660 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9661 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9662 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9663 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9664 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9665 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9666 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9667 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9668 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9669 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9670 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9671 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9672 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9673 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9674 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9675 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9676 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9677 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9678 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9679 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9680 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9681 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9682 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9683 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9684 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9685 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9686 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9687 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9688 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9689 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9690 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9691 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9692 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9693 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9694 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9695 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9696 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9697 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9698 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9699 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9700 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9701 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9702 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9703 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9704 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9705 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9706 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9707 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9708 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9709 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9710 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9711 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9712 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9713 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9714 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9715 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9716 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9717 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9718 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9719 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9720 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9721 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9722 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9723 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9724 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9725 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9726 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9727 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9728 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9729 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9730 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9731 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9732 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9733 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9734 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9735 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9736 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9737 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9738 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9739 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9740 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9741 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9743 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9744 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9745 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9746 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9747 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9748 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9749 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9750 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9751 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9752 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9753 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9754 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9756 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9757 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9758 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9759 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9760 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9761 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9762 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9763 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9764 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9765 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9766 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9767 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9769 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9770 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9771 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9772 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9773 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9774 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9776 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9777 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9778 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9779 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9780 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9781 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9782 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9783 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9784 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9785 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9786 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9787 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9789 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9790 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9802 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9803 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9829 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9830 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9845 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9846 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9863 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9864 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9898 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9899 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9907 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9911 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9912 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9917 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9919 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9920 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9922 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9923 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9924 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9925 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9926 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9927 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9928 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9929 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9930 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9931 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9933 /* Place holder, leave as first spe builtin. */
9934 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9935 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9936 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9937 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9938 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9939 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9940 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9941 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9942 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9943 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9944 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9945 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9946 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9947 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9948 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9949 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9950 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9951 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9952 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9953 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9954 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9955 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9956 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9957 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9958 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9959 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9960 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9961 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9962 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9963 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9964 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9965 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9966 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9967 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9968 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9969 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9970 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9971 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9972 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9973 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9974 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9975 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9976 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9977 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9978 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9979 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9980 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9981 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9982 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9983 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9984 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9985 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9986 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9987 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9988 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9989 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9990 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9991 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9992 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9993 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9994 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9995 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9996 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9997 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9998 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9999 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10000 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10001 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10002 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10003 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10004 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10005 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10006 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10007 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10008 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10009 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10010 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10011 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10012 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10013 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10014 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10015 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10016 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10017 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10018 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10019 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10020 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10021 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10022 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10023 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10024 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10025 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10026 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10027 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10028 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10029 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10030 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10031 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10032 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10033 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10034 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10035 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10036 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10037 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10038 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10039 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10040 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10041 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10042 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10044 /* SPE binary operations expecting a 5-bit unsigned literal. */
10045 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10047 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10048 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10049 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10050 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10051 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10052 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10053 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10054 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10055 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10056 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10057 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10058 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10059 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10060 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10061 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10062 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10063 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10064 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10065 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10066 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10067 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10068 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10069 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10070 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10071 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10072 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10074 /* Place-holder. Leave as last binary SPE builtin. */
10075 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10078 /* AltiVec predicates. */
10080 struct builtin_description_predicates
10082 const unsigned int mask;
10083 const enum insn_code icode;
10084 const char *const name;
10085 const enum rs6000_builtins code;
10088 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10090 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10091 ALTIVEC_BUILTIN_VCMPBFP_P },
10092 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10093 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10094 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10095 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10096 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10097 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10098 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10099 ALTIVEC_BUILTIN_VCMPEQUW_P },
10100 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10101 ALTIVEC_BUILTIN_VCMPGTSW_P },
10102 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10103 ALTIVEC_BUILTIN_VCMPGTUW_P },
10104 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10105 ALTIVEC_BUILTIN_VCMPEQUH_P },
10106 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10107 ALTIVEC_BUILTIN_VCMPGTSH_P },
10108 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10109 ALTIVEC_BUILTIN_VCMPGTUH_P },
10110 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10111 ALTIVEC_BUILTIN_VCMPEQUB_P },
10112 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10113 ALTIVEC_BUILTIN_VCMPGTSB_P },
10114 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10115 ALTIVEC_BUILTIN_VCMPGTUB_P },
10117 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10118 VSX_BUILTIN_XVCMPEQSP_P },
10119 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10120 VSX_BUILTIN_XVCMPGESP_P },
10121 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10122 VSX_BUILTIN_XVCMPGTSP_P },
10123 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10124 VSX_BUILTIN_XVCMPEQDP_P },
10125 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10126 VSX_BUILTIN_XVCMPGEDP_P },
10127 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10128 VSX_BUILTIN_XVCMPGTDP_P },
10130 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10131 ALTIVEC_BUILTIN_VCMPEQ_P },
10132 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10133 ALTIVEC_BUILTIN_VCMPGT_P },
10134 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10135 ALTIVEC_BUILTIN_VCMPGE_P }
10138 /* SPE predicates. */
10139 static struct builtin_description bdesc_spe_predicates[] =
10141 /* Place-holder. Leave as first. */
10142 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10143 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10144 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10145 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10146 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10147 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10148 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10149 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10150 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10151 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10152 /* Place-holder. Leave as last. */
10153 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10156 /* SPE evsel predicates. */
10157 static struct builtin_description bdesc_spe_evsel[] =
10159 /* Place-holder. Leave as first. */
10160 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10161 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10162 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10163 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10164 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10165 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10166 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10167 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10168 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10169 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10170 /* Place-holder. Leave as last. */
10171 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10174 /* PAIRED predicates. */
10175 static const struct builtin_description bdesc_paired_preds[] =
10177 /* Place-holder. Leave as first. */
10178 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10179 /* Place-holder. Leave as last. */
10180 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10183 /* ABS* operations. */
10185 static const struct builtin_description bdesc_abs[] =
10187 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10188 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10189 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10190 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10191 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10192 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10193 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10194 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10195 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10196 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10197 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10200 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10203 static struct builtin_description bdesc_1arg[] =
10205 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10206 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10207 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10208 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10209 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10210 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10211 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10212 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10213 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10214 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10216 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10217 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10218 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10219 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10220 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10221 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10222 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10224 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10225 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10226 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10227 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10228 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10229 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10230 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10232 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10233 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10234 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10235 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10236 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10237 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10238 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10240 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10241 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10242 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10243 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10244 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10245 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10247 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10248 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10249 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10250 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10251 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10252 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10254 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10255 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10256 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10257 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10259 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10260 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10261 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10262 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10263 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10264 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10265 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10266 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10267 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10269 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10270 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10271 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10272 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10273 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10274 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10275 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10276 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10277 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10279 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10280 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10281 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10282 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10283 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10285 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10286 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10287 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10288 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10289 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10290 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10291 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10292 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10293 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10294 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10295 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10296 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10297 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10298 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10299 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10300 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10301 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10302 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10303 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10304 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10306 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10307 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10308 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10310 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10311 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10312 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10313 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10315 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10316 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10317 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10318 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10319 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10320 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10321 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10322 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10323 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10324 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10325 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10326 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10327 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10328 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10329 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10330 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10331 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10332 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10333 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10334 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10335 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10336 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10337 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10338 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10339 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10340 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10341 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10342 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10343 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10344 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10346 /* Place-holder. Leave as last unary SPE builtin. */
10347 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10349 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10350 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10351 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10352 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10353 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10357 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10360 tree arg0 = CALL_EXPR_ARG (exp, 0);
10361 rtx op0 = expand_normal (arg0);
10362 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10363 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10365 if (icode == CODE_FOR_nothing)
10366 /* Builtin not supported on this processor. */
10369 /* If we got invalid arguments bail out before generating bad rtl. */
10370 if (arg0 == error_mark_node)
10373 if (icode == CODE_FOR_altivec_vspltisb
10374 || icode == CODE_FOR_altivec_vspltish
10375 || icode == CODE_FOR_altivec_vspltisw
10376 || icode == CODE_FOR_spe_evsplatfi
10377 || icode == CODE_FOR_spe_evsplati)
10379 /* Only allow 5-bit *signed* literals. */
10380 if (GET_CODE (op0) != CONST_INT
10381 || INTVAL (op0) > 15
10382 || INTVAL (op0) < -16)
10384 error ("argument 1 must be a 5-bit signed literal");
10390 || GET_MODE (target) != tmode
10391 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10392 target = gen_reg_rtx (tmode);
10394 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10395 op0 = copy_to_mode_reg (mode0, op0);
10397 pat = GEN_FCN (icode) (target, op0);
10406 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10408 rtx pat, scratch1, scratch2;
10409 tree arg0 = CALL_EXPR_ARG (exp, 0);
10410 rtx op0 = expand_normal (arg0);
10411 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10412 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10414 /* If we have invalid arguments, bail out before generating bad rtl. */
10415 if (arg0 == error_mark_node)
10419 || GET_MODE (target) != tmode
10420 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10421 target = gen_reg_rtx (tmode);
10423 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10424 op0 = copy_to_mode_reg (mode0, op0);
10426 scratch1 = gen_reg_rtx (mode0);
10427 scratch2 = gen_reg_rtx (mode0);
10429 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10438 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10441 tree arg0 = CALL_EXPR_ARG (exp, 0);
10442 tree arg1 = CALL_EXPR_ARG (exp, 1);
10443 rtx op0 = expand_normal (arg0);
10444 rtx op1 = expand_normal (arg1);
10445 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10446 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10447 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10449 if (icode == CODE_FOR_nothing)
10450 /* Builtin not supported on this processor. */
10453 /* If we got invalid arguments bail out before generating bad rtl. */
10454 if (arg0 == error_mark_node || arg1 == error_mark_node)
10457 if (icode == CODE_FOR_altivec_vcfux
10458 || icode == CODE_FOR_altivec_vcfsx
10459 || icode == CODE_FOR_altivec_vctsxs
10460 || icode == CODE_FOR_altivec_vctuxs
10461 || icode == CODE_FOR_altivec_vspltb
10462 || icode == CODE_FOR_altivec_vsplth
10463 || icode == CODE_FOR_altivec_vspltw
10464 || icode == CODE_FOR_spe_evaddiw
10465 || icode == CODE_FOR_spe_evldd
10466 || icode == CODE_FOR_spe_evldh
10467 || icode == CODE_FOR_spe_evldw
10468 || icode == CODE_FOR_spe_evlhhesplat
10469 || icode == CODE_FOR_spe_evlhhossplat
10470 || icode == CODE_FOR_spe_evlhhousplat
10471 || icode == CODE_FOR_spe_evlwhe
10472 || icode == CODE_FOR_spe_evlwhos
10473 || icode == CODE_FOR_spe_evlwhou
10474 || icode == CODE_FOR_spe_evlwhsplat
10475 || icode == CODE_FOR_spe_evlwwsplat
10476 || icode == CODE_FOR_spe_evrlwi
10477 || icode == CODE_FOR_spe_evslwi
10478 || icode == CODE_FOR_spe_evsrwis
10479 || icode == CODE_FOR_spe_evsubifw
10480 || icode == CODE_FOR_spe_evsrwiu)
10482 /* Only allow 5-bit unsigned literals. */
10484 if (TREE_CODE (arg1) != INTEGER_CST
10485 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10487 error ("argument 2 must be a 5-bit unsigned literal");
10493 || GET_MODE (target) != tmode
10494 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10495 target = gen_reg_rtx (tmode);
10497 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10498 op0 = copy_to_mode_reg (mode0, op0);
10499 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10500 op1 = copy_to_mode_reg (mode1, op1);
10502 pat = GEN_FCN (icode) (target, op0, op1);
10511 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10514 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10515 tree arg0 = CALL_EXPR_ARG (exp, 1);
10516 tree arg1 = CALL_EXPR_ARG (exp, 2);
10517 rtx op0 = expand_normal (arg0);
10518 rtx op1 = expand_normal (arg1);
10519 enum machine_mode tmode = SImode;
10520 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10521 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10524 if (TREE_CODE (cr6_form) != INTEGER_CST)
10526 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10530 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10532 gcc_assert (mode0 == mode1);
10534 /* If we have invalid arguments, bail out before generating bad rtl. */
10535 if (arg0 == error_mark_node || arg1 == error_mark_node)
10539 || GET_MODE (target) != tmode
10540 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10541 target = gen_reg_rtx (tmode);
10543 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10544 op0 = copy_to_mode_reg (mode0, op0);
10545 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10546 op1 = copy_to_mode_reg (mode1, op1);
10548 scratch = gen_reg_rtx (mode0);
10550 pat = GEN_FCN (icode) (scratch, op0, op1);
10555 /* The vec_any* and vec_all* predicates use the same opcodes for two
10556 different operations, but the bits in CR6 will be different
10557 depending on what information we want. So we have to play tricks
10558 with CR6 to get the right bits out.
10560 If you think this is disgusting, look at the specs for the
10561 AltiVec predicates. */
10563 switch (cr6_form_int)
10566 emit_insn (gen_cr6_test_for_zero (target));
10569 emit_insn (gen_cr6_test_for_zero_reverse (target));
10572 emit_insn (gen_cr6_test_for_lt (target));
10575 emit_insn (gen_cr6_test_for_lt_reverse (target));
10578 error ("argument 1 of __builtin_altivec_predicate is out of range");
10586 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10589 tree arg0 = CALL_EXPR_ARG (exp, 0);
10590 tree arg1 = CALL_EXPR_ARG (exp, 1);
10591 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10592 enum machine_mode mode0 = Pmode;
10593 enum machine_mode mode1 = Pmode;
10594 rtx op0 = expand_normal (arg0);
10595 rtx op1 = expand_normal (arg1);
10597 if (icode == CODE_FOR_nothing)
10598 /* Builtin not supported on this processor. */
10601 /* If we got invalid arguments bail out before generating bad rtl. */
10602 if (arg0 == error_mark_node || arg1 == error_mark_node)
10606 || GET_MODE (target) != tmode
10607 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10608 target = gen_reg_rtx (tmode);
10610 op1 = copy_to_mode_reg (mode1, op1);
10612 if (op0 == const0_rtx)
10614 addr = gen_rtx_MEM (tmode, op1);
10618 op0 = copy_to_mode_reg (mode0, op0);
10619 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10622 pat = GEN_FCN (icode) (target, addr);
10632 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10635 tree arg0 = CALL_EXPR_ARG (exp, 0);
10636 tree arg1 = CALL_EXPR_ARG (exp, 1);
10637 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10638 enum machine_mode mode0 = Pmode;
10639 enum machine_mode mode1 = Pmode;
10640 rtx op0 = expand_normal (arg0);
10641 rtx op1 = expand_normal (arg1);
10643 if (icode == CODE_FOR_nothing)
10644 /* Builtin not supported on this processor. */
10647 /* If we got invalid arguments bail out before generating bad rtl. */
10648 if (arg0 == error_mark_node || arg1 == error_mark_node)
10652 || GET_MODE (target) != tmode
10653 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10654 target = gen_reg_rtx (tmode);
10656 op1 = copy_to_mode_reg (mode1, op1);
10658 if (op0 == const0_rtx)
10660 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10664 op0 = copy_to_mode_reg (mode0, op0);
10665 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10668 pat = GEN_FCN (icode) (target, addr);
10678 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10680 tree arg0 = CALL_EXPR_ARG (exp, 0);
10681 tree arg1 = CALL_EXPR_ARG (exp, 1);
10682 tree arg2 = CALL_EXPR_ARG (exp, 2);
10683 rtx op0 = expand_normal (arg0);
10684 rtx op1 = expand_normal (arg1);
10685 rtx op2 = expand_normal (arg2);
10687 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10688 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10689 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10691 /* Invalid arguments. Bail before doing anything stoopid! */
10692 if (arg0 == error_mark_node
10693 || arg1 == error_mark_node
10694 || arg2 == error_mark_node)
10697 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10698 op0 = copy_to_mode_reg (mode2, op0);
10699 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10700 op1 = copy_to_mode_reg (mode0, op1);
10701 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10702 op2 = copy_to_mode_reg (mode1, op2);
10704 pat = GEN_FCN (icode) (op1, op2, op0);
10711 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10713 tree arg0 = CALL_EXPR_ARG (exp, 0);
10714 tree arg1 = CALL_EXPR_ARG (exp, 1);
10715 tree arg2 = CALL_EXPR_ARG (exp, 2);
10716 rtx op0 = expand_normal (arg0);
10717 rtx op1 = expand_normal (arg1);
10718 rtx op2 = expand_normal (arg2);
10720 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10721 enum machine_mode mode1 = Pmode;
10722 enum machine_mode mode2 = Pmode;
10724 /* Invalid arguments. Bail before doing anything stoopid! */
10725 if (arg0 == error_mark_node
10726 || arg1 == error_mark_node
10727 || arg2 == error_mark_node)
10730 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10731 op0 = copy_to_mode_reg (tmode, op0);
10733 op2 = copy_to_mode_reg (mode2, op2);
10735 if (op1 == const0_rtx)
10737 addr = gen_rtx_MEM (tmode, op2);
10741 op1 = copy_to_mode_reg (mode1, op1);
10742 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10745 pat = GEN_FCN (icode) (addr, op0);
10752 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10754 tree arg0 = CALL_EXPR_ARG (exp, 0);
10755 tree arg1 = CALL_EXPR_ARG (exp, 1);
10756 tree arg2 = CALL_EXPR_ARG (exp, 2);
10757 rtx op0 = expand_normal (arg0);
10758 rtx op1 = expand_normal (arg1);
10759 rtx op2 = expand_normal (arg2);
10761 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10762 enum machine_mode smode = insn_data[icode].operand[1].mode;
10763 enum machine_mode mode1 = Pmode;
10764 enum machine_mode mode2 = Pmode;
10766 /* Invalid arguments. Bail before doing anything stoopid! */
10767 if (arg0 == error_mark_node
10768 || arg1 == error_mark_node
10769 || arg2 == error_mark_node)
10772 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
10773 op0 = copy_to_mode_reg (smode, op0);
10775 op2 = copy_to_mode_reg (mode2, op2);
10777 if (op1 == const0_rtx)
10779 addr = gen_rtx_MEM (tmode, op2);
10783 op1 = copy_to_mode_reg (mode1, op1);
10784 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10787 pat = GEN_FCN (icode) (addr, op0);
10794 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10797 tree arg0 = CALL_EXPR_ARG (exp, 0);
10798 tree arg1 = CALL_EXPR_ARG (exp, 1);
10799 tree arg2 = CALL_EXPR_ARG (exp, 2);
10800 rtx op0 = expand_normal (arg0);
10801 rtx op1 = expand_normal (arg1);
10802 rtx op2 = expand_normal (arg2);
10803 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10804 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10805 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10806 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10808 if (icode == CODE_FOR_nothing)
10809 /* Builtin not supported on this processor. */
10812 /* If we got invalid arguments bail out before generating bad rtl. */
10813 if (arg0 == error_mark_node
10814 || arg1 == error_mark_node
10815 || arg2 == error_mark_node)
10818 /* Check and prepare argument depending on the instruction code.
10820 Note that a switch statement instead of the sequence of tests
10821 would be incorrect as many of the CODE_FOR values could be
10822 CODE_FOR_nothing and that would yield multiple alternatives
10823 with identical values. We'd never reach here at runtime in
10825 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10826 || icode == CODE_FOR_altivec_vsldoi_v4si
10827 || icode == CODE_FOR_altivec_vsldoi_v8hi
10828 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10830 /* Only allow 4-bit unsigned literals. */
10832 if (TREE_CODE (arg2) != INTEGER_CST
10833 || TREE_INT_CST_LOW (arg2) & ~0xf)
10835 error ("argument 3 must be a 4-bit unsigned literal");
10839 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10840 || icode == CODE_FOR_vsx_xxpermdi_v2di
10841 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10842 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10843 || icode == CODE_FOR_vsx_xxsldwi_v4si
10844 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10845 || icode == CODE_FOR_vsx_xxsldwi_v2di
10846 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10848 /* Only allow 2-bit unsigned literals. */
10850 if (TREE_CODE (arg2) != INTEGER_CST
10851 || TREE_INT_CST_LOW (arg2) & ~0x3)
10853 error ("argument 3 must be a 2-bit unsigned literal");
10857 else if (icode == CODE_FOR_vsx_set_v2df
10858 || icode == CODE_FOR_vsx_set_v2di)
10860 /* Only allow 1-bit unsigned literals. */
10862 if (TREE_CODE (arg2) != INTEGER_CST
10863 || TREE_INT_CST_LOW (arg2) & ~0x1)
10865 error ("argument 3 must be a 1-bit unsigned literal");
10871 || GET_MODE (target) != tmode
10872 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10873 target = gen_reg_rtx (tmode);
10875 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10876 op0 = copy_to_mode_reg (mode0, op0);
10877 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10878 op1 = copy_to_mode_reg (mode1, op1);
10879 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10880 op2 = copy_to_mode_reg (mode2, op2);
10882 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10883 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10885 pat = GEN_FCN (icode) (target, op0, op1, op2);
10893 /* Expand the lvx builtins. */
10895 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10897 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10898 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10900 enum machine_mode tmode, mode0;
10902 enum insn_code icode;
10906 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10907 icode = CODE_FOR_vector_altivec_load_v16qi;
10909 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10910 icode = CODE_FOR_vector_altivec_load_v8hi;
10912 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10913 icode = CODE_FOR_vector_altivec_load_v4si;
10915 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10916 icode = CODE_FOR_vector_altivec_load_v4sf;
10918 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
10919 icode = CODE_FOR_vector_altivec_load_v2df;
10921 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
10922 icode = CODE_FOR_vector_altivec_load_v2di;
10925 *expandedp = false;
10931 arg0 = CALL_EXPR_ARG (exp, 0);
10932 op0 = expand_normal (arg0);
10933 tmode = insn_data[icode].operand[0].mode;
10934 mode0 = insn_data[icode].operand[1].mode;
10937 || GET_MODE (target) != tmode
10938 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10939 target = gen_reg_rtx (tmode);
10941 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10942 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10944 pat = GEN_FCN (icode) (target, op0);
10951 /* Expand the stvx builtins. */
10953 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10956 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10957 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10959 enum machine_mode mode0, mode1;
10961 enum insn_code icode;
10965 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10966 icode = CODE_FOR_vector_altivec_store_v16qi;
10968 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10969 icode = CODE_FOR_vector_altivec_store_v8hi;
10971 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10972 icode = CODE_FOR_vector_altivec_store_v4si;
10974 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10975 icode = CODE_FOR_vector_altivec_store_v4sf;
10977 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
10978 icode = CODE_FOR_vector_altivec_store_v2df;
10980 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
10981 icode = CODE_FOR_vector_altivec_store_v2di;
10984 *expandedp = false;
10988 arg0 = CALL_EXPR_ARG (exp, 0);
10989 arg1 = CALL_EXPR_ARG (exp, 1);
10990 op0 = expand_normal (arg0);
10991 op1 = expand_normal (arg1);
10992 mode0 = insn_data[icode].operand[0].mode;
10993 mode1 = insn_data[icode].operand[1].mode;
10995 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10996 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10997 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10998 op1 = copy_to_mode_reg (mode1, op1);
11000 pat = GEN_FCN (icode) (op0, op1);
11008 /* Expand the dst builtins. */
11010 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11013 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11014 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11015 tree arg0, arg1, arg2;
11016 enum machine_mode mode0, mode1;
11017 rtx pat, op0, op1, op2;
11018 const struct builtin_description *d;
11021 *expandedp = false;
11023 /* Handle DST variants. */
11025 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11026 if (d->code == fcode)
11028 arg0 = CALL_EXPR_ARG (exp, 0);
11029 arg1 = CALL_EXPR_ARG (exp, 1);
11030 arg2 = CALL_EXPR_ARG (exp, 2);
11031 op0 = expand_normal (arg0);
11032 op1 = expand_normal (arg1);
11033 op2 = expand_normal (arg2);
11034 mode0 = insn_data[d->icode].operand[0].mode;
11035 mode1 = insn_data[d->icode].operand[1].mode;
11037 /* Invalid arguments, bail out before generating bad rtl. */
11038 if (arg0 == error_mark_node
11039 || arg1 == error_mark_node
11040 || arg2 == error_mark_node)
11045 if (TREE_CODE (arg2) != INTEGER_CST
11046 || TREE_INT_CST_LOW (arg2) & ~0x3)
11048 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11052 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11053 op0 = copy_to_mode_reg (Pmode, op0);
11054 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11055 op1 = copy_to_mode_reg (mode1, op1);
11057 pat = GEN_FCN (d->icode) (op0, op1, op2);
11067 /* Expand vec_init builtin. */
11069 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11071 enum machine_mode tmode = TYPE_MODE (type);
11072 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11073 int i, n_elt = GET_MODE_NUNITS (tmode);
11074 rtvec v = rtvec_alloc (n_elt);
11076 gcc_assert (VECTOR_MODE_P (tmode));
11077 gcc_assert (n_elt == call_expr_nargs (exp));
11079 for (i = 0; i < n_elt; ++i)
11081 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11082 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11085 if (!target || !register_operand (target, tmode))
11086 target = gen_reg_rtx (tmode);
11088 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11092 /* Return the integer constant in ARG. Constrain it to be in the range
11093 of the subparts of VEC_TYPE; issue an error if not. */
11096 get_element_number (tree vec_type, tree arg)
11098 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11100 if (!host_integerp (arg, 1)
11101 || (elt = tree_low_cst (arg, 1), elt > max))
11103 error ("selector must be an integer constant in the range 0..%wi", max);
11110 /* Expand vec_set builtin. */
11112 altivec_expand_vec_set_builtin (tree exp)
11114 enum machine_mode tmode, mode1;
11115 tree arg0, arg1, arg2;
11119 arg0 = CALL_EXPR_ARG (exp, 0);
11120 arg1 = CALL_EXPR_ARG (exp, 1);
11121 arg2 = CALL_EXPR_ARG (exp, 2);
11123 tmode = TYPE_MODE (TREE_TYPE (arg0));
11124 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11125 gcc_assert (VECTOR_MODE_P (tmode));
11127 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11128 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11129 elt = get_element_number (TREE_TYPE (arg0), arg2);
11131 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11132 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11134 op0 = force_reg (tmode, op0);
11135 op1 = force_reg (mode1, op1);
11137 rs6000_expand_vector_set (op0, op1, elt);
11142 /* Expand vec_ext builtin. */
11144 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11146 enum machine_mode tmode, mode0;
11151 arg0 = CALL_EXPR_ARG (exp, 0);
11152 arg1 = CALL_EXPR_ARG (exp, 1);
11154 op0 = expand_normal (arg0);
11155 elt = get_element_number (TREE_TYPE (arg0), arg1);
11157 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11158 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11159 gcc_assert (VECTOR_MODE_P (mode0));
11161 op0 = force_reg (mode0, op0);
11163 if (optimize || !target || !register_operand (target, tmode))
11164 target = gen_reg_rtx (tmode);
11166 rs6000_expand_vector_extract (target, op0, elt);
11171 /* Expand the builtin in EXP and store the result in TARGET. Store
11172 true in *EXPANDEDP if we found a builtin to expand. */
11174 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11176 const struct builtin_description *d;
11177 const struct builtin_description_predicates *dp;
11179 enum insn_code icode;
11180 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11183 enum machine_mode tmode, mode0;
11184 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11186 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11187 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11188 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11189 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11192 error ("unresolved overload for Altivec builtin %qF", fndecl);
11196 target = altivec_expand_ld_builtin (exp, target, expandedp);
11200 target = altivec_expand_st_builtin (exp, target, expandedp);
11204 target = altivec_expand_dst_builtin (exp, target, expandedp);
11212 case ALTIVEC_BUILTIN_STVX:
11213 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11214 case ALTIVEC_BUILTIN_STVEBX:
11215 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11216 case ALTIVEC_BUILTIN_STVEHX:
11217 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11218 case ALTIVEC_BUILTIN_STVEWX:
11219 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11220 case ALTIVEC_BUILTIN_STVXL:
11221 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11223 case ALTIVEC_BUILTIN_STVLX:
11224 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11225 case ALTIVEC_BUILTIN_STVLXL:
11226 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11227 case ALTIVEC_BUILTIN_STVRX:
11228 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11229 case ALTIVEC_BUILTIN_STVRXL:
11230 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11232 case VSX_BUILTIN_STXVD2X_V2DF:
11233 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11234 case VSX_BUILTIN_STXVD2X_V2DI:
11235 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11236 case VSX_BUILTIN_STXVW4X_V4SF:
11237 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11238 case VSX_BUILTIN_STXVW4X_V4SI:
11239 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11240 case VSX_BUILTIN_STXVW4X_V8HI:
11241 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11242 case VSX_BUILTIN_STXVW4X_V16QI:
11243 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11245 case ALTIVEC_BUILTIN_MFVSCR:
11246 icode = CODE_FOR_altivec_mfvscr;
11247 tmode = insn_data[icode].operand[0].mode;
11250 || GET_MODE (target) != tmode
11251 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11252 target = gen_reg_rtx (tmode);
11254 pat = GEN_FCN (icode) (target);
11260 case ALTIVEC_BUILTIN_MTVSCR:
11261 icode = CODE_FOR_altivec_mtvscr;
11262 arg0 = CALL_EXPR_ARG (exp, 0);
11263 op0 = expand_normal (arg0);
11264 mode0 = insn_data[icode].operand[0].mode;
11266 /* If we got invalid arguments bail out before generating bad rtl. */
11267 if (arg0 == error_mark_node)
11270 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11271 op0 = copy_to_mode_reg (mode0, op0);
11273 pat = GEN_FCN (icode) (op0);
11278 case ALTIVEC_BUILTIN_DSSALL:
11279 emit_insn (gen_altivec_dssall ());
11282 case ALTIVEC_BUILTIN_DSS:
11283 icode = CODE_FOR_altivec_dss;
11284 arg0 = CALL_EXPR_ARG (exp, 0);
11286 op0 = expand_normal (arg0);
11287 mode0 = insn_data[icode].operand[0].mode;
11289 /* If we got invalid arguments bail out before generating bad rtl. */
11290 if (arg0 == error_mark_node)
11293 if (TREE_CODE (arg0) != INTEGER_CST
11294 || TREE_INT_CST_LOW (arg0) & ~0x3)
11296 error ("argument to dss must be a 2-bit unsigned literal");
11300 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11301 op0 = copy_to_mode_reg (mode0, op0);
11303 emit_insn (gen_altivec_dss (op0));
11306 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11307 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11308 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11309 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11310 case VSX_BUILTIN_VEC_INIT_V2DF:
11311 case VSX_BUILTIN_VEC_INIT_V2DI:
11312 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11314 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11315 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11316 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11317 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11318 case VSX_BUILTIN_VEC_SET_V2DF:
11319 case VSX_BUILTIN_VEC_SET_V2DI:
11320 return altivec_expand_vec_set_builtin (exp);
11322 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11323 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11324 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11325 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11326 case VSX_BUILTIN_VEC_EXT_V2DF:
11327 case VSX_BUILTIN_VEC_EXT_V2DI:
11328 return altivec_expand_vec_ext_builtin (exp, target);
11332 /* Fall through. */
11335 /* Expand abs* operations. */
11337 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11338 if (d->code == fcode)
11339 return altivec_expand_abs_builtin (d->icode, exp, target);
11341 /* Expand the AltiVec predicates. */
11342 dp = bdesc_altivec_preds;
11343 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11344 if (dp->code == fcode)
11345 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11347 /* LV* are funky. We initialized them differently. */
11350 case ALTIVEC_BUILTIN_LVSL:
11351 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11352 exp, target, false);
11353 case ALTIVEC_BUILTIN_LVSR:
11354 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11355 exp, target, false);
11356 case ALTIVEC_BUILTIN_LVEBX:
11357 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11358 exp, target, false);
11359 case ALTIVEC_BUILTIN_LVEHX:
11360 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11361 exp, target, false);
11362 case ALTIVEC_BUILTIN_LVEWX:
11363 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11364 exp, target, false);
11365 case ALTIVEC_BUILTIN_LVXL:
11366 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11367 exp, target, false);
11368 case ALTIVEC_BUILTIN_LVX:
11369 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11370 exp, target, false);
11371 case ALTIVEC_BUILTIN_LVLX:
11372 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11373 exp, target, true);
11374 case ALTIVEC_BUILTIN_LVLXL:
11375 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11376 exp, target, true);
11377 case ALTIVEC_BUILTIN_LVRX:
11378 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11379 exp, target, true);
11380 case ALTIVEC_BUILTIN_LVRXL:
11381 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11382 exp, target, true);
11383 case VSX_BUILTIN_LXVD2X_V2DF:
11384 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11385 exp, target, false);
11386 case VSX_BUILTIN_LXVD2X_V2DI:
11387 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11388 exp, target, false);
11389 case VSX_BUILTIN_LXVW4X_V4SF:
11390 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11391 exp, target, false);
11392 case VSX_BUILTIN_LXVW4X_V4SI:
11393 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11394 exp, target, false);
11395 case VSX_BUILTIN_LXVW4X_V8HI:
11396 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11397 exp, target, false);
11398 case VSX_BUILTIN_LXVW4X_V16QI:
11399 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11400 exp, target, false);
11404 /* Fall through. */
11407 *expandedp = false;
11411 /* Expand the builtin in EXP and store the result in TARGET. Store
11412 true in *EXPANDEDP if we found a builtin to expand. */
11414 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11416 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11417 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11418 const struct builtin_description *d;
11425 case PAIRED_BUILTIN_STX:
11426 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11427 case PAIRED_BUILTIN_LX:
11428 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11431 /* Fall through. */
11434 /* Expand the paired predicates. */
11435 d = bdesc_paired_preds;
11436 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11437 if (d->code == fcode)
11438 return paired_expand_predicate_builtin (d->icode, exp, target);
11440 *expandedp = false;
11444 /* Binops that need to be initialized manually, but can be expanded
11445 automagically by rs6000_expand_binop_builtin. */
11446 static struct builtin_description bdesc_2arg_spe[] =
11448 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11449 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11450 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11451 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11452 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11453 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11454 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11455 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11456 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11457 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11458 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11459 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11460 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11461 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11462 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11463 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11464 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11465 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11466 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11467 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11468 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11469 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11472 /* Expand the builtin in EXP and store the result in TARGET. Store
11473 true in *EXPANDEDP if we found a builtin to expand.
11475 This expands the SPE builtins that are not simple unary and binary
11478 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11480 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11482 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11483 enum insn_code icode;
11484 enum machine_mode tmode, mode0;
11486 struct builtin_description *d;
11491 /* Syntax check for a 5-bit unsigned immediate. */
11494 case SPE_BUILTIN_EVSTDD:
11495 case SPE_BUILTIN_EVSTDH:
11496 case SPE_BUILTIN_EVSTDW:
11497 case SPE_BUILTIN_EVSTWHE:
11498 case SPE_BUILTIN_EVSTWHO:
11499 case SPE_BUILTIN_EVSTWWE:
11500 case SPE_BUILTIN_EVSTWWO:
11501 arg1 = CALL_EXPR_ARG (exp, 2);
11502 if (TREE_CODE (arg1) != INTEGER_CST
11503 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11505 error ("argument 2 must be a 5-bit unsigned literal");
11513 /* The evsplat*i instructions are not quite generic. */
11516 case SPE_BUILTIN_EVSPLATFI:
11517 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11519 case SPE_BUILTIN_EVSPLATI:
11520 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11526 d = (struct builtin_description *) bdesc_2arg_spe;
11527 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11528 if (d->code == fcode)
11529 return rs6000_expand_binop_builtin (d->icode, exp, target);
11531 d = (struct builtin_description *) bdesc_spe_predicates;
11532 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11533 if (d->code == fcode)
11534 return spe_expand_predicate_builtin (d->icode, exp, target);
11536 d = (struct builtin_description *) bdesc_spe_evsel;
11537 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11538 if (d->code == fcode)
11539 return spe_expand_evsel_builtin (d->icode, exp, target);
11543 case SPE_BUILTIN_EVSTDDX:
11544 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11545 case SPE_BUILTIN_EVSTDHX:
11546 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11547 case SPE_BUILTIN_EVSTDWX:
11548 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11549 case SPE_BUILTIN_EVSTWHEX:
11550 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11551 case SPE_BUILTIN_EVSTWHOX:
11552 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11553 case SPE_BUILTIN_EVSTWWEX:
11554 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11555 case SPE_BUILTIN_EVSTWWOX:
11556 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11557 case SPE_BUILTIN_EVSTDD:
11558 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11559 case SPE_BUILTIN_EVSTDH:
11560 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11561 case SPE_BUILTIN_EVSTDW:
11562 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11563 case SPE_BUILTIN_EVSTWHE:
11564 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11565 case SPE_BUILTIN_EVSTWHO:
11566 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11567 case SPE_BUILTIN_EVSTWWE:
11568 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11569 case SPE_BUILTIN_EVSTWWO:
11570 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11571 case SPE_BUILTIN_MFSPEFSCR:
11572 icode = CODE_FOR_spe_mfspefscr;
11573 tmode = insn_data[icode].operand[0].mode;
11576 || GET_MODE (target) != tmode
11577 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11578 target = gen_reg_rtx (tmode);
11580 pat = GEN_FCN (icode) (target);
11585 case SPE_BUILTIN_MTSPEFSCR:
11586 icode = CODE_FOR_spe_mtspefscr;
11587 arg0 = CALL_EXPR_ARG (exp, 0);
11588 op0 = expand_normal (arg0);
11589 mode0 = insn_data[icode].operand[0].mode;
11591 if (arg0 == error_mark_node)
11594 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11595 op0 = copy_to_mode_reg (mode0, op0);
11597 pat = GEN_FCN (icode) (op0);
11605 *expandedp = false;
11610 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11612 rtx pat, scratch, tmp;
11613 tree form = CALL_EXPR_ARG (exp, 0);
11614 tree arg0 = CALL_EXPR_ARG (exp, 1);
11615 tree arg1 = CALL_EXPR_ARG (exp, 2);
11616 rtx op0 = expand_normal (arg0);
11617 rtx op1 = expand_normal (arg1);
11618 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11619 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11621 enum rtx_code code;
11623 if (TREE_CODE (form) != INTEGER_CST)
11625 error ("argument 1 of __builtin_paired_predicate must be a constant");
11629 form_int = TREE_INT_CST_LOW (form);
11631 gcc_assert (mode0 == mode1);
11633 if (arg0 == error_mark_node || arg1 == error_mark_node)
11637 || GET_MODE (target) != SImode
11638 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11639 target = gen_reg_rtx (SImode);
11640 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11641 op0 = copy_to_mode_reg (mode0, op0);
11642 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11643 op1 = copy_to_mode_reg (mode1, op1);
11645 scratch = gen_reg_rtx (CCFPmode);
11647 pat = GEN_FCN (icode) (scratch, op0, op1);
11669 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11672 error ("argument 1 of __builtin_paired_predicate is out of range");
11676 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11677 emit_move_insn (target, tmp);
11682 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11684 rtx pat, scratch, tmp;
11685 tree form = CALL_EXPR_ARG (exp, 0);
11686 tree arg0 = CALL_EXPR_ARG (exp, 1);
11687 tree arg1 = CALL_EXPR_ARG (exp, 2);
11688 rtx op0 = expand_normal (arg0);
11689 rtx op1 = expand_normal (arg1);
11690 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11691 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11693 enum rtx_code code;
11695 if (TREE_CODE (form) != INTEGER_CST)
11697 error ("argument 1 of __builtin_spe_predicate must be a constant");
11701 form_int = TREE_INT_CST_LOW (form);
11703 gcc_assert (mode0 == mode1);
11705 if (arg0 == error_mark_node || arg1 == error_mark_node)
11709 || GET_MODE (target) != SImode
11710 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11711 target = gen_reg_rtx (SImode);
11713 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11714 op0 = copy_to_mode_reg (mode0, op0);
11715 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11716 op1 = copy_to_mode_reg (mode1, op1);
11718 scratch = gen_reg_rtx (CCmode);
11720 pat = GEN_FCN (icode) (scratch, op0, op1);
11725 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11726 _lower_. We use one compare, but look in different bits of the
11727 CR for each variant.
11729 There are 2 elements in each SPE simd type (upper/lower). The CR
11730 bits are set as follows:
11732 BIT0 | BIT 1 | BIT 2 | BIT 3
11733 U | L | (U | L) | (U & L)
11735 So, for an "all" relationship, BIT 3 would be set.
11736 For an "any" relationship, BIT 2 would be set. Etc.
11738 Following traditional nomenclature, these bits map to:
11740 BIT0 | BIT 1 | BIT 2 | BIT 3
11743 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11748 /* All variant. OV bit. */
11750 /* We need to get to the OV bit, which is the ORDERED bit. We
11751 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11752 that's ugly and will make validate_condition_mode die.
11753 So let's just use another pattern. */
11754 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11756 /* Any variant. EQ bit. */
11760 /* Upper variant. LT bit. */
11764 /* Lower variant. GT bit. */
11769 error ("argument 1 of __builtin_spe_predicate is out of range");
11773 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11774 emit_move_insn (target, tmp);
11779 /* The evsel builtins look like this:
11781 e = __builtin_spe_evsel_OP (a, b, c, d);
11783 and work like this:
11785 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11786 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11790 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11793 tree arg0 = CALL_EXPR_ARG (exp, 0);
11794 tree arg1 = CALL_EXPR_ARG (exp, 1);
11795 tree arg2 = CALL_EXPR_ARG (exp, 2);
11796 tree arg3 = CALL_EXPR_ARG (exp, 3);
11797 rtx op0 = expand_normal (arg0);
11798 rtx op1 = expand_normal (arg1);
11799 rtx op2 = expand_normal (arg2);
11800 rtx op3 = expand_normal (arg3);
11801 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11802 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11804 gcc_assert (mode0 == mode1);
11806 if (arg0 == error_mark_node || arg1 == error_mark_node
11807 || arg2 == error_mark_node || arg3 == error_mark_node)
11811 || GET_MODE (target) != mode0
11812 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11813 target = gen_reg_rtx (mode0);
11815 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11816 op0 = copy_to_mode_reg (mode0, op0);
11817 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11818 op1 = copy_to_mode_reg (mode0, op1);
11819 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11820 op2 = copy_to_mode_reg (mode0, op2);
11821 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11822 op3 = copy_to_mode_reg (mode0, op3);
11824 /* Generate the compare. */
11825 scratch = gen_reg_rtx (CCmode);
11826 pat = GEN_FCN (icode) (scratch, op0, op1);
11831 if (mode0 == V2SImode)
11832 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11834 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11839 /* Expand an expression EXP that calls a built-in function,
11840 with result going to TARGET if that's convenient
11841 (and in mode MODE if that's convenient).
11842 SUBTARGET may be used as the target for computing one of EXP's operands.
11843 IGNORE is nonzero if the value is to be ignored. */
11846 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11847 enum machine_mode mode ATTRIBUTE_UNUSED,
11848 int ignore ATTRIBUTE_UNUSED)
11850 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11851 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11852 const struct builtin_description *d;
11859 case RS6000_BUILTIN_RECIP:
11860 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11862 case RS6000_BUILTIN_RECIPF:
11863 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11865 case RS6000_BUILTIN_RSQRTF:
11866 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11868 case RS6000_BUILTIN_RSQRT:
11869 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11871 case RS6000_BUILTIN_BSWAP_HI:
11872 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11874 case POWER7_BUILTIN_BPERMD:
11875 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11876 ? CODE_FOR_bpermd_di
11877 : CODE_FOR_bpermd_si), exp, target);
11879 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11880 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11882 int icode = (int) CODE_FOR_altivec_lvsr;
11883 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11884 enum machine_mode mode = insn_data[icode].operand[1].mode;
11888 gcc_assert (TARGET_ALTIVEC);
11890 arg = CALL_EXPR_ARG (exp, 0);
11891 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11892 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11893 addr = memory_address (mode, op);
11894 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11898 /* For the load case need to negate the address. */
11899 op = gen_reg_rtx (GET_MODE (addr));
11900 emit_insn (gen_rtx_SET (VOIDmode, op,
11901 gen_rtx_NEG (GET_MODE (addr), addr)));
11903 op = gen_rtx_MEM (mode, op);
11906 || GET_MODE (target) != tmode
11907 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11908 target = gen_reg_rtx (tmode);
11910 /*pat = gen_altivec_lvsr (target, op);*/
11911 pat = GEN_FCN (icode) (target, op);
11919 case ALTIVEC_BUILTIN_VCFUX:
11920 case ALTIVEC_BUILTIN_VCFSX:
11921 case ALTIVEC_BUILTIN_VCTUXS:
11922 case ALTIVEC_BUILTIN_VCTSXS:
11923 /* FIXME: There's got to be a nicer way to handle this case than
11924 constructing a new CALL_EXPR. */
11925 if (call_expr_nargs (exp) == 1)
11927 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11928 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11936 if (TARGET_ALTIVEC)
11938 ret = altivec_expand_builtin (exp, target, &success);
11945 ret = spe_expand_builtin (exp, target, &success);
11950 if (TARGET_PAIRED_FLOAT)
11952 ret = paired_expand_builtin (exp, target, &success);
11958 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11960 /* Handle simple unary operations. */
11961 d = (struct builtin_description *) bdesc_1arg;
11962 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11963 if (d->code == fcode)
11964 return rs6000_expand_unop_builtin (d->icode, exp, target);
11966 /* Handle simple binary operations. */
11967 d = (struct builtin_description *) bdesc_2arg;
11968 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11969 if (d->code == fcode)
11970 return rs6000_expand_binop_builtin (d->icode, exp, target);
11972 /* Handle simple ternary operations. */
11974 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11975 if (d->code == fcode)
11976 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11978 gcc_unreachable ();
11982 rs6000_init_builtins (void)
11987 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11988 V2SF_type_node = build_vector_type (float_type_node, 2);
11989 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11990 V2DF_type_node = build_vector_type (double_type_node, 2);
11991 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11992 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11993 V4SF_type_node = build_vector_type (float_type_node, 4);
11994 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11995 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11997 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11998 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11999 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12000 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12002 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12003 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12004 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12005 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12007 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12008 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12009 'vector unsigned short'. */
12011 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12012 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12013 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12014 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12015 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12017 long_integer_type_internal_node = long_integer_type_node;
12018 long_unsigned_type_internal_node = long_unsigned_type_node;
12019 long_long_integer_type_internal_node = long_long_integer_type_node;
12020 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12021 intQI_type_internal_node = intQI_type_node;
12022 uintQI_type_internal_node = unsigned_intQI_type_node;
12023 intHI_type_internal_node = intHI_type_node;
12024 uintHI_type_internal_node = unsigned_intHI_type_node;
12025 intSI_type_internal_node = intSI_type_node;
12026 uintSI_type_internal_node = unsigned_intSI_type_node;
12027 intDI_type_internal_node = intDI_type_node;
12028 uintDI_type_internal_node = unsigned_intDI_type_node;
12029 float_type_internal_node = float_type_node;
12030 double_type_internal_node = double_type_node;
12031 void_type_internal_node = void_type_node;
12033 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12035 builtin_mode_to_type[QImode][0] = integer_type_node;
12036 builtin_mode_to_type[HImode][0] = integer_type_node;
12037 builtin_mode_to_type[SImode][0] = intSI_type_node;
12038 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12039 builtin_mode_to_type[DImode][0] = intDI_type_node;
12040 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12041 builtin_mode_to_type[SFmode][0] = float_type_node;
12042 builtin_mode_to_type[DFmode][0] = double_type_node;
12043 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12044 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12045 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12046 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12047 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12048 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12049 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12050 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12051 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12052 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12053 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12054 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12055 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12057 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12058 get_identifier ("__bool char"),
12059 bool_char_type_node);
12060 TYPE_NAME (bool_char_type_node) = tdecl;
12061 (*lang_hooks.decls.pushdecl) (tdecl);
12062 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12063 get_identifier ("__bool short"),
12064 bool_short_type_node);
12065 TYPE_NAME (bool_short_type_node) = tdecl;
12066 (*lang_hooks.decls.pushdecl) (tdecl);
12067 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12068 get_identifier ("__bool int"),
12069 bool_int_type_node);
12070 TYPE_NAME (bool_int_type_node) = tdecl;
12071 (*lang_hooks.decls.pushdecl) (tdecl);
12072 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12074 TYPE_NAME (pixel_type_node) = tdecl;
12075 (*lang_hooks.decls.pushdecl) (tdecl);
12077 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12078 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12079 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12080 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12081 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12083 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12084 get_identifier ("__vector unsigned char"),
12085 unsigned_V16QI_type_node);
12086 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12087 (*lang_hooks.decls.pushdecl) (tdecl);
12088 tdecl = build_decl (BUILTINS_LOCATION,
12089 TYPE_DECL, get_identifier ("__vector signed char"),
12091 TYPE_NAME (V16QI_type_node) = tdecl;
12092 (*lang_hooks.decls.pushdecl) (tdecl);
12093 tdecl = build_decl (BUILTINS_LOCATION,
12094 TYPE_DECL, get_identifier ("__vector __bool char"),
12095 bool_V16QI_type_node);
12096 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12097 (*lang_hooks.decls.pushdecl) (tdecl);
12099 tdecl = build_decl (BUILTINS_LOCATION,
12100 TYPE_DECL, get_identifier ("__vector unsigned short"),
12101 unsigned_V8HI_type_node);
12102 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12103 (*lang_hooks.decls.pushdecl) (tdecl);
12104 tdecl = build_decl (BUILTINS_LOCATION,
12105 TYPE_DECL, get_identifier ("__vector signed short"),
12107 TYPE_NAME (V8HI_type_node) = tdecl;
12108 (*lang_hooks.decls.pushdecl) (tdecl);
12109 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12110 get_identifier ("__vector __bool short"),
12111 bool_V8HI_type_node);
12112 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12113 (*lang_hooks.decls.pushdecl) (tdecl);
12115 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12116 get_identifier ("__vector unsigned int"),
12117 unsigned_V4SI_type_node);
12118 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12119 (*lang_hooks.decls.pushdecl) (tdecl);
12120 tdecl = build_decl (BUILTINS_LOCATION,
12121 TYPE_DECL, get_identifier ("__vector signed int"),
12123 TYPE_NAME (V4SI_type_node) = tdecl;
12124 (*lang_hooks.decls.pushdecl) (tdecl);
12125 tdecl = build_decl (BUILTINS_LOCATION,
12126 TYPE_DECL, get_identifier ("__vector __bool int"),
12127 bool_V4SI_type_node);
12128 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12129 (*lang_hooks.decls.pushdecl) (tdecl);
12131 tdecl = build_decl (BUILTINS_LOCATION,
12132 TYPE_DECL, get_identifier ("__vector float"),
12134 TYPE_NAME (V4SF_type_node) = tdecl;
12135 (*lang_hooks.decls.pushdecl) (tdecl);
12136 tdecl = build_decl (BUILTINS_LOCATION,
12137 TYPE_DECL, get_identifier ("__vector __pixel"),
12138 pixel_V8HI_type_node);
12139 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12140 (*lang_hooks.decls.pushdecl) (tdecl);
12144 tdecl = build_decl (BUILTINS_LOCATION,
12145 TYPE_DECL, get_identifier ("__vector double"),
12147 TYPE_NAME (V2DF_type_node) = tdecl;
12148 (*lang_hooks.decls.pushdecl) (tdecl);
12150 tdecl = build_decl (BUILTINS_LOCATION,
12151 TYPE_DECL, get_identifier ("__vector long"),
12153 TYPE_NAME (V2DI_type_node) = tdecl;
12154 (*lang_hooks.decls.pushdecl) (tdecl);
12156 tdecl = build_decl (BUILTINS_LOCATION,
12157 TYPE_DECL, get_identifier ("__vector unsigned long"),
12158 unsigned_V2DI_type_node);
12159 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12160 (*lang_hooks.decls.pushdecl) (tdecl);
12162 tdecl = build_decl (BUILTINS_LOCATION,
12163 TYPE_DECL, get_identifier ("__vector __bool long"),
12164 bool_V2DI_type_node);
12165 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12166 (*lang_hooks.decls.pushdecl) (tdecl);
12169 if (TARGET_PAIRED_FLOAT)
12170 paired_init_builtins ();
12172 spe_init_builtins ();
12173 if (TARGET_ALTIVEC)
12174 altivec_init_builtins ();
12175 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12176 rs6000_common_init_builtins ();
12179 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12180 RS6000_BUILTIN_RECIP,
12181 "__builtin_recipdiv");
12182 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12183 RS6000_BUILTIN_RECIP);
12187 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12188 RS6000_BUILTIN_RECIPF,
12189 "__builtin_recipdivf");
12190 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12191 RS6000_BUILTIN_RECIPF);
12193 if (TARGET_FRSQRTE)
12195 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12196 RS6000_BUILTIN_RSQRT,
12197 "__builtin_rsqrt");
12198 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12199 RS6000_BUILTIN_RSQRT);
12201 if (TARGET_FRSQRTES)
12203 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12204 RS6000_BUILTIN_RSQRTF,
12205 "__builtin_rsqrtf");
12206 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12207 RS6000_BUILTIN_RSQRTF);
12209 if (TARGET_POPCNTD)
12211 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12212 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12213 POWER7_BUILTIN_BPERMD,
12214 "__builtin_bpermd");
12215 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12216 POWER7_BUILTIN_BPERMD);
12218 if (TARGET_POWERPC)
12220 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12221 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12222 unsigned_intHI_type_node,
12224 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12225 RS6000_BUILTIN_BSWAP_HI);
12229 /* AIX libm provides clog as __clog. */
12230 if (built_in_decls [BUILT_IN_CLOG])
12231 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12234 #ifdef SUBTARGET_INIT_BUILTINS
12235 SUBTARGET_INIT_BUILTINS;
12239 /* Returns the rs6000 builtin decl for CODE. */
12242 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12244 if (code >= RS6000_BUILTIN_COUNT)
12245 return error_mark_node;
12247 return rs6000_builtin_decls[code];
12250 /* Search through a set of builtins and enable the mask bits.
12251 DESC is an array of builtins.
12252 SIZE is the total number of builtins.
12253 START is the builtin enum at which to start.
12254 END is the builtin enum at which to end. */
12256 enable_mask_for_builtins (struct builtin_description *desc, int size,
12257 enum rs6000_builtins start,
12258 enum rs6000_builtins end)
12262 for (i = 0; i < size; ++i)
12263 if (desc[i].code == start)
12269 for (; i < size; ++i)
12271 /* Flip all the bits on. */
12272 desc[i].mask = target_flags;
12273 if (desc[i].code == end)
12279 spe_init_builtins (void)
12281 tree puint_type_node = build_pointer_type (unsigned_type_node);
12282 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12283 struct builtin_description *d;
12286 tree v2si_ftype_4_v2si
12287 = build_function_type_list (opaque_V2SI_type_node,
12288 opaque_V2SI_type_node,
12289 opaque_V2SI_type_node,
12290 opaque_V2SI_type_node,
12291 opaque_V2SI_type_node,
12294 tree v2sf_ftype_4_v2sf
12295 = build_function_type_list (opaque_V2SF_type_node,
12296 opaque_V2SF_type_node,
12297 opaque_V2SF_type_node,
12298 opaque_V2SF_type_node,
12299 opaque_V2SF_type_node,
12302 tree int_ftype_int_v2si_v2si
12303 = build_function_type_list (integer_type_node,
12305 opaque_V2SI_type_node,
12306 opaque_V2SI_type_node,
12309 tree int_ftype_int_v2sf_v2sf
12310 = build_function_type_list (integer_type_node,
12312 opaque_V2SF_type_node,
12313 opaque_V2SF_type_node,
12316 tree void_ftype_v2si_puint_int
12317 = build_function_type_list (void_type_node,
12318 opaque_V2SI_type_node,
12323 tree void_ftype_v2si_puint_char
12324 = build_function_type_list (void_type_node,
12325 opaque_V2SI_type_node,
12330 tree void_ftype_v2si_pv2si_int
12331 = build_function_type_list (void_type_node,
12332 opaque_V2SI_type_node,
12333 opaque_p_V2SI_type_node,
12337 tree void_ftype_v2si_pv2si_char
12338 = build_function_type_list (void_type_node,
12339 opaque_V2SI_type_node,
12340 opaque_p_V2SI_type_node,
12344 tree void_ftype_int
12345 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12347 tree int_ftype_void
12348 = build_function_type_list (integer_type_node, NULL_TREE);
12350 tree v2si_ftype_pv2si_int
12351 = build_function_type_list (opaque_V2SI_type_node,
12352 opaque_p_V2SI_type_node,
12356 tree v2si_ftype_puint_int
12357 = build_function_type_list (opaque_V2SI_type_node,
12362 tree v2si_ftype_pushort_int
12363 = build_function_type_list (opaque_V2SI_type_node,
12368 tree v2si_ftype_signed_char
12369 = build_function_type_list (opaque_V2SI_type_node,
12370 signed_char_type_node,
12373 /* The initialization of the simple binary and unary builtins is
12374 done in rs6000_common_init_builtins, but we have to enable the
12375 mask bits here manually because we have run out of `target_flags'
12376 bits. We really need to redesign this mask business. */
12378 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12379 ARRAY_SIZE (bdesc_2arg),
12380 SPE_BUILTIN_EVADDW,
12381 SPE_BUILTIN_EVXOR);
12382 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12383 ARRAY_SIZE (bdesc_1arg),
12385 SPE_BUILTIN_EVSUBFUSIAAW);
12386 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12387 ARRAY_SIZE (bdesc_spe_predicates),
12388 SPE_BUILTIN_EVCMPEQ,
12389 SPE_BUILTIN_EVFSTSTLT);
12390 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12391 ARRAY_SIZE (bdesc_spe_evsel),
12392 SPE_BUILTIN_EVSEL_CMPGTS,
12393 SPE_BUILTIN_EVSEL_FSTSTEQ);
12395 (*lang_hooks.decls.pushdecl)
12396 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12397 get_identifier ("__ev64_opaque__"),
12398 opaque_V2SI_type_node));
12400 /* Initialize irregular SPE builtins. */
12402 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12403 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12404 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12405 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12406 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12407 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12408 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12409 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12410 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12411 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12412 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12413 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12414 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12415 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12416 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12417 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12418 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12419 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12422 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12423 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12424 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12425 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12426 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12427 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12428 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12429 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12430 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12431 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12432 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12433 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12434 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12435 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12436 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12437 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12438 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12439 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12440 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12441 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12442 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12443 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12446 d = (struct builtin_description *) bdesc_spe_predicates;
12447 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12451 switch (insn_data[d->icode].operand[1].mode)
12454 type = int_ftype_int_v2si_v2si;
12457 type = int_ftype_int_v2sf_v2sf;
12460 gcc_unreachable ();
12463 def_builtin (d->mask, d->name, type, d->code);
12466 /* Evsel predicates. */
12467 d = (struct builtin_description *) bdesc_spe_evsel;
12468 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12472 switch (insn_data[d->icode].operand[1].mode)
12475 type = v2si_ftype_4_v2si;
12478 type = v2sf_ftype_4_v2sf;
12481 gcc_unreachable ();
12484 def_builtin (d->mask, d->name, type, d->code);
12489 paired_init_builtins (void)
12491 const struct builtin_description *d;
12494 tree int_ftype_int_v2sf_v2sf
12495 = build_function_type_list (integer_type_node,
12500 tree pcfloat_type_node =
12501 build_pointer_type (build_qualified_type
12502 (float_type_node, TYPE_QUAL_CONST));
12504 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12505 long_integer_type_node,
12508 tree void_ftype_v2sf_long_pcfloat =
12509 build_function_type_list (void_type_node,
12511 long_integer_type_node,
12516 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12517 PAIRED_BUILTIN_LX);
12520 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12521 PAIRED_BUILTIN_STX);
12524 d = bdesc_paired_preds;
12525 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12529 switch (insn_data[d->icode].operand[1].mode)
12532 type = int_ftype_int_v2sf_v2sf;
12535 gcc_unreachable ();
12538 def_builtin (d->mask, d->name, type, d->code);
12543 altivec_init_builtins (void)
12545 const struct builtin_description *d;
12546 const struct builtin_description_predicates *dp;
12550 tree pvoid_type_node = build_pointer_type (void_type_node);
12552 tree pcvoid_type_node
12553 = build_pointer_type (build_qualified_type (void_type_node,
12556 tree int_ftype_opaque
12557 = build_function_type_list (integer_type_node,
12558 opaque_V4SI_type_node, NULL_TREE);
12559 tree opaque_ftype_opaque
12560 = build_function_type_list (integer_type_node, NULL_TREE);
12561 tree opaque_ftype_opaque_int
12562 = build_function_type_list (opaque_V4SI_type_node,
12563 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12564 tree opaque_ftype_opaque_opaque_int
12565 = build_function_type_list (opaque_V4SI_type_node,
12566 opaque_V4SI_type_node, opaque_V4SI_type_node,
12567 integer_type_node, NULL_TREE);
12568 tree int_ftype_int_opaque_opaque
12569 = build_function_type_list (integer_type_node,
12570 integer_type_node, opaque_V4SI_type_node,
12571 opaque_V4SI_type_node, NULL_TREE);
12572 tree int_ftype_int_v4si_v4si
12573 = build_function_type_list (integer_type_node,
12574 integer_type_node, V4SI_type_node,
12575 V4SI_type_node, NULL_TREE);
12576 tree void_ftype_v4si
12577 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12578 tree v8hi_ftype_void
12579 = build_function_type_list (V8HI_type_node, NULL_TREE);
12580 tree void_ftype_void
12581 = build_function_type_list (void_type_node, NULL_TREE);
12582 tree void_ftype_int
12583 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12585 tree opaque_ftype_long_pcvoid
12586 = build_function_type_list (opaque_V4SI_type_node,
12587 long_integer_type_node, pcvoid_type_node,
12589 tree v16qi_ftype_long_pcvoid
12590 = build_function_type_list (V16QI_type_node,
12591 long_integer_type_node, pcvoid_type_node,
12593 tree v8hi_ftype_long_pcvoid
12594 = build_function_type_list (V8HI_type_node,
12595 long_integer_type_node, pcvoid_type_node,
12597 tree v4si_ftype_long_pcvoid
12598 = build_function_type_list (V4SI_type_node,
12599 long_integer_type_node, pcvoid_type_node,
12601 tree v4sf_ftype_long_pcvoid
12602 = build_function_type_list (V4SF_type_node,
12603 long_integer_type_node, pcvoid_type_node,
12605 tree v2df_ftype_long_pcvoid
12606 = build_function_type_list (V2DF_type_node,
12607 long_integer_type_node, pcvoid_type_node,
12609 tree v2di_ftype_long_pcvoid
12610 = build_function_type_list (V2DI_type_node,
12611 long_integer_type_node, pcvoid_type_node,
12614 tree void_ftype_opaque_long_pvoid
12615 = build_function_type_list (void_type_node,
12616 opaque_V4SI_type_node, long_integer_type_node,
12617 pvoid_type_node, NULL_TREE);
12618 tree void_ftype_v4si_long_pvoid
12619 = build_function_type_list (void_type_node,
12620 V4SI_type_node, long_integer_type_node,
12621 pvoid_type_node, NULL_TREE);
12622 tree void_ftype_v16qi_long_pvoid
12623 = build_function_type_list (void_type_node,
12624 V16QI_type_node, long_integer_type_node,
12625 pvoid_type_node, NULL_TREE);
12626 tree void_ftype_v8hi_long_pvoid
12627 = build_function_type_list (void_type_node,
12628 V8HI_type_node, long_integer_type_node,
12629 pvoid_type_node, NULL_TREE);
12630 tree void_ftype_v4sf_long_pvoid
12631 = build_function_type_list (void_type_node,
12632 V4SF_type_node, long_integer_type_node,
12633 pvoid_type_node, NULL_TREE);
12634 tree void_ftype_v2df_long_pvoid
12635 = build_function_type_list (void_type_node,
12636 V2DF_type_node, long_integer_type_node,
12637 pvoid_type_node, NULL_TREE);
12638 tree void_ftype_v2di_long_pvoid
12639 = build_function_type_list (void_type_node,
12640 V2DI_type_node, long_integer_type_node,
12641 pvoid_type_node, NULL_TREE);
12642 tree int_ftype_int_v8hi_v8hi
12643 = build_function_type_list (integer_type_node,
12644 integer_type_node, V8HI_type_node,
12645 V8HI_type_node, NULL_TREE);
12646 tree int_ftype_int_v16qi_v16qi
12647 = build_function_type_list (integer_type_node,
12648 integer_type_node, V16QI_type_node,
12649 V16QI_type_node, NULL_TREE);
12650 tree int_ftype_int_v4sf_v4sf
12651 = build_function_type_list (integer_type_node,
12652 integer_type_node, V4SF_type_node,
12653 V4SF_type_node, NULL_TREE);
12654 tree int_ftype_int_v2df_v2df
12655 = build_function_type_list (integer_type_node,
12656 integer_type_node, V2DF_type_node,
12657 V2DF_type_node, NULL_TREE);
12658 tree v4si_ftype_v4si
12659 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12660 tree v8hi_ftype_v8hi
12661 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12662 tree v16qi_ftype_v16qi
12663 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12664 tree v4sf_ftype_v4sf
12665 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12666 tree v2df_ftype_v2df
12667 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12668 tree void_ftype_pcvoid_int_int
12669 = build_function_type_list (void_type_node,
12670 pcvoid_type_node, integer_type_node,
12671 integer_type_node, NULL_TREE);
12673 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12674 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12675 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12676 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12677 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12678 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12679 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12680 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12681 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12682 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12683 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12684 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12685 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12686 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12687 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12688 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12689 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12690 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12691 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12692 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12693 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12694 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12695 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12696 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12697 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12698 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12699 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12700 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12701 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12702 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12704 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12705 VSX_BUILTIN_LXVD2X_V2DF);
12706 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12707 VSX_BUILTIN_LXVD2X_V2DI);
12708 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12709 VSX_BUILTIN_LXVW4X_V4SF);
12710 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12711 VSX_BUILTIN_LXVW4X_V4SI);
12712 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12713 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12714 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12715 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12716 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12717 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12718 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12719 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12720 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12721 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12722 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12723 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12724 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12725 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12726 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12727 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
12728 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
12729 VSX_BUILTIN_VEC_LD);
12730 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
12731 VSX_BUILTIN_VEC_ST);
12733 if (rs6000_cpu == PROCESSOR_CELL)
12735 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12736 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12737 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12738 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12740 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12741 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12742 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12743 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12745 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12746 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12747 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12748 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12750 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12751 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12752 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12753 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12755 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12756 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12757 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12759 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12760 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12761 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12762 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12763 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12764 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12765 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12766 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12767 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12768 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12769 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12770 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12772 /* Add the DST variants. */
12774 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12775 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12777 /* Initialize the predicates. */
12778 dp = bdesc_altivec_preds;
12779 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12781 enum machine_mode mode1;
12783 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12784 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12785 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12786 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12791 mode1 = insn_data[dp->icode].operand[1].mode;
12796 type = int_ftype_int_opaque_opaque;
12799 type = int_ftype_int_v4si_v4si;
12802 type = int_ftype_int_v8hi_v8hi;
12805 type = int_ftype_int_v16qi_v16qi;
12808 type = int_ftype_int_v4sf_v4sf;
12811 type = int_ftype_int_v2df_v2df;
12814 gcc_unreachable ();
12817 def_builtin (dp->mask, dp->name, type, dp->code);
12820 /* Initialize the abs* operators. */
12822 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12824 enum machine_mode mode0;
12827 mode0 = insn_data[d->icode].operand[0].mode;
12832 type = v4si_ftype_v4si;
12835 type = v8hi_ftype_v8hi;
12838 type = v16qi_ftype_v16qi;
12841 type = v4sf_ftype_v4sf;
12844 type = v2df_ftype_v2df;
12847 gcc_unreachable ();
12850 def_builtin (d->mask, d->name, type, d->code);
12853 if (TARGET_ALTIVEC)
12857 /* Initialize target builtin that implements
12858 targetm.vectorize.builtin_mask_for_load. */
12860 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12861 v16qi_ftype_long_pcvoid,
12862 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12863 BUILT_IN_MD, NULL, NULL_TREE);
12864 TREE_READONLY (decl) = 1;
12865 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12866 altivec_builtin_mask_for_load = decl;
12869 /* Access to the vec_init patterns. */
12870 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12871 integer_type_node, integer_type_node,
12872 integer_type_node, NULL_TREE);
12873 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12874 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12876 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12877 short_integer_type_node,
12878 short_integer_type_node,
12879 short_integer_type_node,
12880 short_integer_type_node,
12881 short_integer_type_node,
12882 short_integer_type_node,
12883 short_integer_type_node, NULL_TREE);
12884 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12885 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12887 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12888 char_type_node, char_type_node,
12889 char_type_node, char_type_node,
12890 char_type_node, char_type_node,
12891 char_type_node, char_type_node,
12892 char_type_node, char_type_node,
12893 char_type_node, char_type_node,
12894 char_type_node, char_type_node,
12895 char_type_node, NULL_TREE);
12896 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12897 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12899 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12900 float_type_node, float_type_node,
12901 float_type_node, NULL_TREE);
12902 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12903 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12907 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12908 double_type_node, NULL_TREE);
12909 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12910 VSX_BUILTIN_VEC_INIT_V2DF);
12912 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12913 intDI_type_node, NULL_TREE);
12914 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12915 VSX_BUILTIN_VEC_INIT_V2DI);
12918 /* Access to the vec_set patterns. */
12919 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12921 integer_type_node, NULL_TREE);
12922 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12923 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12925 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12927 integer_type_node, NULL_TREE);
12928 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12929 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12931 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12933 integer_type_node, NULL_TREE);
12934 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12935 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12937 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12939 integer_type_node, NULL_TREE);
12940 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12941 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12945 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12947 integer_type_node, NULL_TREE);
12948 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12949 VSX_BUILTIN_VEC_SET_V2DF);
12951 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12953 integer_type_node, NULL_TREE);
12954 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12955 VSX_BUILTIN_VEC_SET_V2DI);
12958 /* Access to the vec_extract patterns. */
12959 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12960 integer_type_node, NULL_TREE);
12961 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12962 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12964 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12965 integer_type_node, NULL_TREE);
12966 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12967 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12969 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12970 integer_type_node, NULL_TREE);
12971 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12972 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12974 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12975 integer_type_node, NULL_TREE);
12976 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12977 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12981 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12982 integer_type_node, NULL_TREE);
12983 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12984 VSX_BUILTIN_VEC_EXT_V2DF);
12986 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12987 integer_type_node, NULL_TREE);
12988 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12989 VSX_BUILTIN_VEC_EXT_V2DI);
12993 /* Hash function for builtin functions with up to 3 arguments and a return
12996 builtin_hash_function (const void *hash_entry)
13000 const struct builtin_hash_struct *bh =
13001 (const struct builtin_hash_struct *) hash_entry;
13003 for (i = 0; i < 4; i++)
13005 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13006 ret = (ret * 2) + bh->uns_p[i];
13012 /* Compare builtin hash entries H1 and H2 for equivalence. */
13014 builtin_hash_eq (const void *h1, const void *h2)
13016 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13017 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13019 return ((p1->mode[0] == p2->mode[0])
13020 && (p1->mode[1] == p2->mode[1])
13021 && (p1->mode[2] == p2->mode[2])
13022 && (p1->mode[3] == p2->mode[3])
13023 && (p1->uns_p[0] == p2->uns_p[0])
13024 && (p1->uns_p[1] == p2->uns_p[1])
13025 && (p1->uns_p[2] == p2->uns_p[2])
13026 && (p1->uns_p[3] == p2->uns_p[3]));
13029 /* Map types for builtin functions with an explicit return type and up to 3
13030 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13031 of the argument. */
13033 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13034 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13035 enum rs6000_builtins builtin, const char *name)
13037 struct builtin_hash_struct h;
13038 struct builtin_hash_struct *h2;
13042 tree ret_type = NULL_TREE;
13043 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13045 /* Create builtin_hash_table. */
13046 if (builtin_hash_table == NULL)
13047 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13048 builtin_hash_eq, NULL);
13050 h.type = NULL_TREE;
13051 h.mode[0] = mode_ret;
13052 h.mode[1] = mode_arg0;
13053 h.mode[2] = mode_arg1;
13054 h.mode[3] = mode_arg2;
13060 /* If the builtin is a type that produces unsigned results or takes unsigned
13061 arguments, and it is returned as a decl for the vectorizer (such as
13062 widening multiplies, permute), make sure the arguments and return value
13063 are type correct. */
13066 /* unsigned 2 argument functions. */
13067 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13068 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13069 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13070 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13076 /* unsigned 3 argument functions. */
13077 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13078 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13079 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13080 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13081 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13082 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13083 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13084 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13085 case VSX_BUILTIN_VPERM_16QI_UNS:
13086 case VSX_BUILTIN_VPERM_8HI_UNS:
13087 case VSX_BUILTIN_VPERM_4SI_UNS:
13088 case VSX_BUILTIN_VPERM_2DI_UNS:
13089 case VSX_BUILTIN_XXSEL_16QI_UNS:
13090 case VSX_BUILTIN_XXSEL_8HI_UNS:
13091 case VSX_BUILTIN_XXSEL_4SI_UNS:
13092 case VSX_BUILTIN_XXSEL_2DI_UNS:
13099 /* signed permute functions with unsigned char mask. */
13100 case ALTIVEC_BUILTIN_VPERM_16QI:
13101 case ALTIVEC_BUILTIN_VPERM_8HI:
13102 case ALTIVEC_BUILTIN_VPERM_4SI:
13103 case ALTIVEC_BUILTIN_VPERM_4SF:
13104 case ALTIVEC_BUILTIN_VPERM_2DI:
13105 case ALTIVEC_BUILTIN_VPERM_2DF:
13106 case VSX_BUILTIN_VPERM_16QI:
13107 case VSX_BUILTIN_VPERM_8HI:
13108 case VSX_BUILTIN_VPERM_4SI:
13109 case VSX_BUILTIN_VPERM_4SF:
13110 case VSX_BUILTIN_VPERM_2DI:
13111 case VSX_BUILTIN_VPERM_2DF:
13115 /* unsigned args, signed return. */
13116 case VSX_BUILTIN_XVCVUXDDP_UNS:
13117 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13121 /* signed args, unsigned return. */
13122 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13123 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13131 /* Figure out how many args are present. */
13132 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13136 fatal_error ("internal error: builtin function %s had no type", name);
13138 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13139 if (!ret_type && h.uns_p[0])
13140 ret_type = builtin_mode_to_type[h.mode[0]][0];
13143 fatal_error ("internal error: builtin function %s had an unexpected "
13144 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13146 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13147 arg_type[i] = NULL_TREE;
13149 for (i = 0; i < num_args; i++)
13151 int m = (int) h.mode[i+1];
13152 int uns_p = h.uns_p[i+1];
13154 arg_type[i] = builtin_mode_to_type[m][uns_p];
13155 if (!arg_type[i] && uns_p)
13156 arg_type[i] = builtin_mode_to_type[m][0];
13159 fatal_error ("internal error: builtin function %s, argument %d "
13160 "had unexpected argument type %s", name, i,
13161 GET_MODE_NAME (m));
13164 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13165 if (*found == NULL)
13167 h2 = ggc_alloc_builtin_hash_struct ();
13169 *found = (void *)h2;
13171 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13172 arg_type[2], NULL_TREE);
13175 return ((struct builtin_hash_struct *)(*found))->type;
13179 rs6000_common_init_builtins (void)
13181 const struct builtin_description *d;
13184 tree opaque_ftype_opaque = NULL_TREE;
13185 tree opaque_ftype_opaque_opaque = NULL_TREE;
13186 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13187 tree v2si_ftype_qi = NULL_TREE;
13188 tree v2si_ftype_v2si_qi = NULL_TREE;
13189 tree v2si_ftype_int_qi = NULL_TREE;
13191 if (!TARGET_PAIRED_FLOAT)
13193 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13194 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13197 /* Add the ternary operators. */
13199 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13202 int mask = d->mask;
13204 if ((mask != 0 && (mask & target_flags) == 0)
13205 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13208 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13209 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13210 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13211 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13213 if (! (type = opaque_ftype_opaque_opaque_opaque))
13214 type = opaque_ftype_opaque_opaque_opaque
13215 = build_function_type_list (opaque_V4SI_type_node,
13216 opaque_V4SI_type_node,
13217 opaque_V4SI_type_node,
13218 opaque_V4SI_type_node,
13223 enum insn_code icode = d->icode;
13224 if (d->name == 0 || icode == CODE_FOR_nothing)
13227 type = builtin_function_type (insn_data[icode].operand[0].mode,
13228 insn_data[icode].operand[1].mode,
13229 insn_data[icode].operand[2].mode,
13230 insn_data[icode].operand[3].mode,
13234 def_builtin (d->mask, d->name, type, d->code);
13237 /* Add the binary operators. */
13239 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13241 enum machine_mode mode0, mode1, mode2;
13243 int mask = d->mask;
13245 if ((mask != 0 && (mask & target_flags) == 0)
13246 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13249 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13250 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13251 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13252 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13254 if (! (type = opaque_ftype_opaque_opaque))
13255 type = opaque_ftype_opaque_opaque
13256 = build_function_type_list (opaque_V4SI_type_node,
13257 opaque_V4SI_type_node,
13258 opaque_V4SI_type_node,
13263 enum insn_code icode = d->icode;
13264 if (d->name == 0 || icode == CODE_FOR_nothing)
13267 mode0 = insn_data[icode].operand[0].mode;
13268 mode1 = insn_data[icode].operand[1].mode;
13269 mode2 = insn_data[icode].operand[2].mode;
13271 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13273 if (! (type = v2si_ftype_v2si_qi))
13274 type = v2si_ftype_v2si_qi
13275 = build_function_type_list (opaque_V2SI_type_node,
13276 opaque_V2SI_type_node,
13281 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13282 && mode2 == QImode)
13284 if (! (type = v2si_ftype_int_qi))
13285 type = v2si_ftype_int_qi
13286 = build_function_type_list (opaque_V2SI_type_node,
13293 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13297 def_builtin (d->mask, d->name, type, d->code);
13300 /* Add the simple unary operators. */
13301 d = (struct builtin_description *) bdesc_1arg;
13302 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13304 enum machine_mode mode0, mode1;
13306 int mask = d->mask;
13308 if ((mask != 0 && (mask & target_flags) == 0)
13309 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13312 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13313 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13314 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13315 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13317 if (! (type = opaque_ftype_opaque))
13318 type = opaque_ftype_opaque
13319 = build_function_type_list (opaque_V4SI_type_node,
13320 opaque_V4SI_type_node,
13325 enum insn_code icode = d->icode;
13326 if (d->name == 0 || icode == CODE_FOR_nothing)
13329 mode0 = insn_data[icode].operand[0].mode;
13330 mode1 = insn_data[icode].operand[1].mode;
13332 if (mode0 == V2SImode && mode1 == QImode)
13334 if (! (type = v2si_ftype_qi))
13335 type = v2si_ftype_qi
13336 = build_function_type_list (opaque_V2SI_type_node,
13342 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13346 def_builtin (d->mask, d->name, type, d->code);
13351 rs6000_init_libfuncs (void)
13353 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13354 && !TARGET_POWER2 && !TARGET_POWERPC)
13356 /* AIX library routines for float->int conversion. */
13357 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13358 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13359 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13360 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13363 if (!TARGET_IEEEQUAD)
13364 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13365 if (!TARGET_XL_COMPAT)
13367 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13368 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13369 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13370 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13372 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13374 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13375 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13376 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13377 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13378 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13379 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13380 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13382 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13383 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13384 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13385 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13386 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13387 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13388 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13389 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13392 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13393 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13397 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13398 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13399 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13400 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13404 /* 32-bit SVR4 quad floating point routines. */
13406 set_optab_libfunc (add_optab, TFmode, "_q_add");
13407 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13408 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13409 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13410 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13411 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13412 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13414 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13415 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13416 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13417 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13418 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13419 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13421 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13422 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13423 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13424 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13425 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13426 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13427 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13428 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13433 /* Expand a block clear operation, and return 1 if successful. Return 0
13434 if we should let the compiler generate normal code.
13436 operands[0] is the destination
13437 operands[1] is the length
13438 operands[3] is the alignment */
13441 expand_block_clear (rtx operands[])
13443 rtx orig_dest = operands[0];
13444 rtx bytes_rtx = operands[1];
13445 rtx align_rtx = operands[3];
13446 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13447 HOST_WIDE_INT align;
13448 HOST_WIDE_INT bytes;
13453 /* If this is not a fixed size move, just call memcpy */
13457 /* This must be a fixed size alignment */
13458 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13459 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13461 /* Anything to clear? */
13462 bytes = INTVAL (bytes_rtx);
13466 /* Use the builtin memset after a point, to avoid huge code bloat.
13467 When optimize_size, avoid any significant code bloat; calling
13468 memset is about 4 instructions, so allow for one instruction to
13469 load zero and three to do clearing. */
13470 if (TARGET_ALTIVEC && align >= 128)
13472 else if (TARGET_POWERPC64 && align >= 32)
13474 else if (TARGET_SPE && align >= 64)
13479 if (optimize_size && bytes > 3 * clear_step)
13481 if (! optimize_size && bytes > 8 * clear_step)
13484 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13486 enum machine_mode mode = BLKmode;
13489 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13494 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13499 else if (bytes >= 8 && TARGET_POWERPC64
13500 /* 64-bit loads and stores require word-aligned
13502 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13507 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13508 { /* move 4 bytes */
13512 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13513 { /* move 2 bytes */
13517 else /* move 1 byte at a time */
13523 dest = adjust_address (orig_dest, mode, offset);
13525 emit_move_insn (dest, CONST0_RTX (mode));
13532 /* Expand a block move operation, and return 1 if successful. Return 0
13533 if we should let the compiler generate normal code.
13535 operands[0] is the destination
13536 operands[1] is the source
13537 operands[2] is the length
13538 operands[3] is the alignment */
13540 #define MAX_MOVE_REG 4
13543 expand_block_move (rtx operands[])
13545 rtx orig_dest = operands[0];
13546 rtx orig_src = operands[1];
13547 rtx bytes_rtx = operands[2];
13548 rtx align_rtx = operands[3];
13549 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13554 rtx stores[MAX_MOVE_REG];
13557 /* If this is not a fixed size move, just call memcpy */
13561 /* This must be a fixed size alignment */
13562 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13563 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13565 /* Anything to move? */
13566 bytes = INTVAL (bytes_rtx);
13570 if (bytes > rs6000_block_move_inline_limit)
13573 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13576 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13577 rtx (*mov) (rtx, rtx);
13579 enum machine_mode mode = BLKmode;
13582 /* Altivec first, since it will be faster than a string move
13583 when it applies, and usually not significantly larger. */
13584 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13588 gen_func.mov = gen_movv4si;
13590 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13594 gen_func.mov = gen_movv2si;
13596 else if (TARGET_STRING
13597 && bytes > 24 /* move up to 32 bytes at a time */
13603 && ! fixed_regs[10]
13604 && ! fixed_regs[11]
13605 && ! fixed_regs[12])
13607 move_bytes = (bytes > 32) ? 32 : bytes;
13608 gen_func.movmemsi = gen_movmemsi_8reg;
13610 else if (TARGET_STRING
13611 && bytes > 16 /* move up to 24 bytes at a time */
13617 && ! fixed_regs[10])
13619 move_bytes = (bytes > 24) ? 24 : bytes;
13620 gen_func.movmemsi = gen_movmemsi_6reg;
13622 else if (TARGET_STRING
13623 && bytes > 8 /* move up to 16 bytes at a time */
13627 && ! fixed_regs[8])
13629 move_bytes = (bytes > 16) ? 16 : bytes;
13630 gen_func.movmemsi = gen_movmemsi_4reg;
13632 else if (bytes >= 8 && TARGET_POWERPC64
13633 /* 64-bit loads and stores require word-aligned
13635 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13639 gen_func.mov = gen_movdi;
13641 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13642 { /* move up to 8 bytes at a time */
13643 move_bytes = (bytes > 8) ? 8 : bytes;
13644 gen_func.movmemsi = gen_movmemsi_2reg;
13646 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13647 { /* move 4 bytes */
13650 gen_func.mov = gen_movsi;
13652 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13653 { /* move 2 bytes */
13656 gen_func.mov = gen_movhi;
13658 else if (TARGET_STRING && bytes > 1)
13659 { /* move up to 4 bytes at a time */
13660 move_bytes = (bytes > 4) ? 4 : bytes;
13661 gen_func.movmemsi = gen_movmemsi_1reg;
13663 else /* move 1 byte at a time */
13667 gen_func.mov = gen_movqi;
13670 src = adjust_address (orig_src, mode, offset);
13671 dest = adjust_address (orig_dest, mode, offset);
13673 if (mode != BLKmode)
13675 rtx tmp_reg = gen_reg_rtx (mode);
13677 emit_insn ((*gen_func.mov) (tmp_reg, src));
13678 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13681 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13684 for (i = 0; i < num_reg; i++)
13685 emit_insn (stores[i]);
13689 if (mode == BLKmode)
13691 /* Move the address into scratch registers. The movmemsi
13692 patterns require zero offset. */
13693 if (!REG_P (XEXP (src, 0)))
13695 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13696 src = replace_equiv_address (src, src_reg);
13698 set_mem_size (src, GEN_INT (move_bytes));
13700 if (!REG_P (XEXP (dest, 0)))
13702 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13703 dest = replace_equiv_address (dest, dest_reg);
13705 set_mem_size (dest, GEN_INT (move_bytes));
13707 emit_insn ((*gen_func.movmemsi) (dest, src,
13708 GEN_INT (move_bytes & 31),
13717 /* Return a string to perform a load_multiple operation.
13718 operands[0] is the vector.
13719 operands[1] is the source address.
13720 operands[2] is the first destination register. */
13723 rs6000_output_load_multiple (rtx operands[3])
13725 /* We have to handle the case where the pseudo used to contain the address
13726 is assigned to one of the output registers. */
13728 int words = XVECLEN (operands[0], 0);
13731 if (XVECLEN (operands[0], 0) == 1)
13732 return "{l|lwz} %2,0(%1)";
13734 for (i = 0; i < words; i++)
13735 if (refers_to_regno_p (REGNO (operands[2]) + i,
13736 REGNO (operands[2]) + i + 1, operands[1], 0))
13740 xop[0] = GEN_INT (4 * (words-1));
13741 xop[1] = operands[1];
13742 xop[2] = operands[2];
13743 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13748 xop[0] = GEN_INT (4 * (words-1));
13749 xop[1] = operands[1];
13750 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13751 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);
13756 for (j = 0; j < words; j++)
13759 xop[0] = GEN_INT (j * 4);
13760 xop[1] = operands[1];
13761 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13762 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13764 xop[0] = GEN_INT (i * 4);
13765 xop[1] = operands[1];
13766 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13771 return "{lsi|lswi} %2,%1,%N0";
13775 /* A validation routine: say whether CODE, a condition code, and MODE
13776 match. The other alternatives either don't make sense or should
13777 never be generated. */
13780 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13782 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13783 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13784 && GET_MODE_CLASS (mode) == MODE_CC);
13786 /* These don't make sense. */
13787 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13788 || mode != CCUNSmode);
13790 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13791 || mode == CCUNSmode);
13793 gcc_assert (mode == CCFPmode
13794 || (code != ORDERED && code != UNORDERED
13795 && code != UNEQ && code != LTGT
13796 && code != UNGT && code != UNLT
13797 && code != UNGE && code != UNLE));
13799 /* These should never be generated except for
13800 flag_finite_math_only. */
13801 gcc_assert (mode != CCFPmode
13802 || flag_finite_math_only
13803 || (code != LE && code != GE
13804 && code != UNEQ && code != LTGT
13805 && code != UNGT && code != UNLT));
13807 /* These are invalid; the information is not there. */
13808 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13812 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13813 mask required to convert the result of a rotate insn into a shift
13814 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13817 includes_lshift_p (rtx shiftop, rtx andop)
13819 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13821 shift_mask <<= INTVAL (shiftop);
13823 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13826 /* Similar, but for right shift. */
13829 includes_rshift_p (rtx shiftop, rtx andop)
13831 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13833 shift_mask >>= INTVAL (shiftop);
13835 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13838 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13839 to perform a left shift. It must have exactly SHIFTOP least
13840 significant 0's, then one or more 1's, then zero or more 0's. */
13843 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13845 if (GET_CODE (andop) == CONST_INT)
13847 HOST_WIDE_INT c, lsb, shift_mask;
13849 c = INTVAL (andop);
13850 if (c == 0 || c == ~0)
13854 shift_mask <<= INTVAL (shiftop);
13856 /* Find the least significant one bit. */
13859 /* It must coincide with the LSB of the shift mask. */
13860 if (-lsb != shift_mask)
13863 /* Invert to look for the next transition (if any). */
13866 /* Remove the low group of ones (originally low group of zeros). */
13869 /* Again find the lsb, and check we have all 1's above. */
13873 else if (GET_CODE (andop) == CONST_DOUBLE
13874 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13876 HOST_WIDE_INT low, high, lsb;
13877 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13879 low = CONST_DOUBLE_LOW (andop);
13880 if (HOST_BITS_PER_WIDE_INT < 64)
13881 high = CONST_DOUBLE_HIGH (andop);
13883 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13884 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13887 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13889 shift_mask_high = ~0;
13890 if (INTVAL (shiftop) > 32)
13891 shift_mask_high <<= INTVAL (shiftop) - 32;
13893 lsb = high & -high;
13895 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13901 lsb = high & -high;
13902 return high == -lsb;
13905 shift_mask_low = ~0;
13906 shift_mask_low <<= INTVAL (shiftop);
13910 if (-lsb != shift_mask_low)
13913 if (HOST_BITS_PER_WIDE_INT < 64)
13918 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13920 lsb = high & -high;
13921 return high == -lsb;
13925 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13931 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13932 to perform a left shift. It must have SHIFTOP or more least
13933 significant 0's, with the remainder of the word 1's. */
13936 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13938 if (GET_CODE (andop) == CONST_INT)
13940 HOST_WIDE_INT c, lsb, shift_mask;
13943 shift_mask <<= INTVAL (shiftop);
13944 c = INTVAL (andop);
13946 /* Find the least significant one bit. */
13949 /* It must be covered by the shift mask.
13950 This test also rejects c == 0. */
13951 if ((lsb & shift_mask) == 0)
13954 /* Check we have all 1's above the transition, and reject all 1's. */
13955 return c == -lsb && lsb != 1;
13957 else if (GET_CODE (andop) == CONST_DOUBLE
13958 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13960 HOST_WIDE_INT low, lsb, shift_mask_low;
13962 low = CONST_DOUBLE_LOW (andop);
13964 if (HOST_BITS_PER_WIDE_INT < 64)
13966 HOST_WIDE_INT high, shift_mask_high;
13968 high = CONST_DOUBLE_HIGH (andop);
13972 shift_mask_high = ~0;
13973 if (INTVAL (shiftop) > 32)
13974 shift_mask_high <<= INTVAL (shiftop) - 32;
13976 lsb = high & -high;
13978 if ((lsb & shift_mask_high) == 0)
13981 return high == -lsb;
13987 shift_mask_low = ~0;
13988 shift_mask_low <<= INTVAL (shiftop);
13992 if ((lsb & shift_mask_low) == 0)
13995 return low == -lsb && lsb != 1;
14001 /* Return 1 if operands will generate a valid arguments to rlwimi
14002 instruction for insert with right shift in 64-bit mode. The mask may
14003 not start on the first bit or stop on the last bit because wrap-around
14004 effects of instruction do not correspond to semantics of RTL insn. */
14007 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14009 if (INTVAL (startop) > 32
14010 && INTVAL (startop) < 64
14011 && INTVAL (sizeop) > 1
14012 && INTVAL (sizeop) + INTVAL (startop) < 64
14013 && INTVAL (shiftop) > 0
14014 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14015 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14021 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14022 for lfq and stfq insns iff the registers are hard registers. */
14025 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14027 /* We might have been passed a SUBREG. */
14028 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14031 /* We might have been passed non floating point registers. */
14032 if (!FP_REGNO_P (REGNO (reg1))
14033 || !FP_REGNO_P (REGNO (reg2)))
14036 return (REGNO (reg1) == REGNO (reg2) - 1);
14039 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14040 addr1 and addr2 must be in consecutive memory locations
14041 (addr2 == addr1 + 8). */
14044 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14047 unsigned int reg1, reg2;
14048 int offset1, offset2;
14050 /* The mems cannot be volatile. */
14051 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14054 addr1 = XEXP (mem1, 0);
14055 addr2 = XEXP (mem2, 0);
14057 /* Extract an offset (if used) from the first addr. */
14058 if (GET_CODE (addr1) == PLUS)
14060 /* If not a REG, return zero. */
14061 if (GET_CODE (XEXP (addr1, 0)) != REG)
14065 reg1 = REGNO (XEXP (addr1, 0));
14066 /* The offset must be constant! */
14067 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14069 offset1 = INTVAL (XEXP (addr1, 1));
14072 else if (GET_CODE (addr1) != REG)
14076 reg1 = REGNO (addr1);
14077 /* This was a simple (mem (reg)) expression. Offset is 0. */
14081 /* And now for the second addr. */
14082 if (GET_CODE (addr2) == PLUS)
14084 /* If not a REG, return zero. */
14085 if (GET_CODE (XEXP (addr2, 0)) != REG)
14089 reg2 = REGNO (XEXP (addr2, 0));
14090 /* The offset must be constant. */
14091 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14093 offset2 = INTVAL (XEXP (addr2, 1));
14096 else if (GET_CODE (addr2) != REG)
14100 reg2 = REGNO (addr2);
14101 /* This was a simple (mem (reg)) expression. Offset is 0. */
14105 /* Both of these must have the same base register. */
14109 /* The offset for the second addr must be 8 more than the first addr. */
14110 if (offset2 != offset1 + 8)
14113 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14120 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14122 static bool eliminated = false;
14125 if (mode != SDmode)
14126 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14129 rtx mem = cfun->machine->sdmode_stack_slot;
14130 gcc_assert (mem != NULL_RTX);
14134 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14135 cfun->machine->sdmode_stack_slot = mem;
14141 if (TARGET_DEBUG_ADDR)
14143 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14144 GET_MODE_NAME (mode));
14146 fprintf (stderr, "\tNULL_RTX\n");
14155 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14157 /* Don't walk into types. */
14158 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14160 *walk_subtrees = 0;
14164 switch (TREE_CODE (*tp))
14173 case VIEW_CONVERT_EXPR:
14174 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14184 enum reload_reg_type {
14186 VECTOR_REGISTER_TYPE,
14187 OTHER_REGISTER_TYPE
14190 static enum reload_reg_type
14191 rs6000_reload_register_type (enum reg_class rclass)
14197 return GPR_REGISTER_TYPE;
14202 return VECTOR_REGISTER_TYPE;
14205 return OTHER_REGISTER_TYPE;
14209 /* Inform reload about cases where moving X with a mode MODE to a register in
14210 RCLASS requires an extra scratch or immediate register. Return the class
14211 needed for the immediate register.
14213 For VSX and Altivec, we may need a register to convert sp+offset into
14216 For misaligned 64-bit gpr loads and stores we need a register to
14217 convert an offset address to indirect. */
14220 rs6000_secondary_reload (bool in_p,
14222 reg_class_t rclass_i,
14223 enum machine_mode mode,
14224 secondary_reload_info *sri)
14226 enum reg_class rclass = (enum reg_class) rclass_i;
14227 reg_class_t ret = ALL_REGS;
14228 enum insn_code icode;
14229 bool default_p = false;
14231 sri->icode = CODE_FOR_nothing;
14233 /* Convert vector loads and stores into gprs to use an additional base
14235 icode = rs6000_vector_reload[mode][in_p != false];
14236 if (icode != CODE_FOR_nothing)
14239 sri->icode = CODE_FOR_nothing;
14240 sri->extra_cost = 0;
14242 if (GET_CODE (x) == MEM)
14244 rtx addr = XEXP (x, 0);
14246 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14247 an extra register in that case, but it would need an extra
14248 register if the addressing is reg+reg or (reg+reg)&(-16). */
14249 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14251 if (!legitimate_indirect_address_p (addr, false)
14252 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14254 sri->icode = icode;
14255 /* account for splitting the loads, and converting the
14256 address from reg+reg to reg. */
14257 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14258 + ((GET_CODE (addr) == AND) ? 1 : 0));
14261 /* Loads to and stores from vector registers can only do reg+reg
14262 addressing. Altivec registers can also do (reg+reg)&(-16). */
14263 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14264 || rclass == FLOAT_REGS || rclass == NO_REGS)
14266 if (!VECTOR_MEM_ALTIVEC_P (mode)
14267 && GET_CODE (addr) == AND
14268 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14269 && INTVAL (XEXP (addr, 1)) == -16
14270 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14271 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14273 sri->icode = icode;
14274 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14277 else if (!legitimate_indirect_address_p (addr, false)
14278 && (rclass == NO_REGS
14279 || !legitimate_indexed_address_p (addr, false)))
14281 sri->icode = icode;
14282 sri->extra_cost = 1;
14285 icode = CODE_FOR_nothing;
14287 /* Any other loads, including to pseudo registers which haven't been
14288 assigned to a register yet, default to require a scratch
14292 sri->icode = icode;
14293 sri->extra_cost = 2;
14296 else if (REG_P (x))
14298 int regno = true_regnum (x);
14300 icode = CODE_FOR_nothing;
14301 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14305 enum reg_class xclass = REGNO_REG_CLASS (regno);
14306 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14307 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14309 /* If memory is needed, use default_secondary_reload to create the
14311 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14320 else if (TARGET_POWERPC64
14321 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14323 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14325 rtx addr = XEXP (x, 0);
14327 if (GET_CODE (addr) == PRE_MODIFY)
14328 addr = XEXP (addr, 1);
14329 else if (GET_CODE (addr) == LO_SUM
14330 && GET_CODE (XEXP (addr, 0)) == REG
14331 && GET_CODE (XEXP (addr, 1)) == CONST)
14332 addr = XEXP (XEXP (addr, 1), 0);
14334 if (GET_CODE (addr) == PLUS
14335 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14336 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14339 sri->icode = CODE_FOR_reload_di_load;
14341 sri->icode = CODE_FOR_reload_di_store;
14342 sri->extra_cost = 2;
14352 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14354 gcc_assert (ret != ALL_REGS);
14356 if (TARGET_DEBUG_ADDR)
14359 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14361 reg_class_names[ret],
14362 in_p ? "true" : "false",
14363 reg_class_names[rclass],
14364 GET_MODE_NAME (mode));
14367 fprintf (stderr, ", default secondary reload");
14369 if (sri->icode != CODE_FOR_nothing)
14370 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14371 insn_data[sri->icode].name, sri->extra_cost);
14373 fprintf (stderr, "\n");
14381 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14382 to SP+reg addressing. */
14385 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14387 int regno = true_regnum (reg);
14388 enum machine_mode mode = GET_MODE (reg);
14389 enum reg_class rclass;
14391 rtx and_op2 = NULL_RTX;
14394 rtx scratch_or_premodify = scratch;
14398 if (TARGET_DEBUG_ADDR)
14400 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14401 store_p ? "store" : "load");
14402 fprintf (stderr, "reg:\n");
14404 fprintf (stderr, "mem:\n");
14406 fprintf (stderr, "scratch:\n");
14407 debug_rtx (scratch);
14410 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14411 gcc_assert (GET_CODE (mem) == MEM);
14412 rclass = REGNO_REG_CLASS (regno);
14413 addr = XEXP (mem, 0);
14417 /* GPRs can handle reg + small constant, all other addresses need to use
14418 the scratch register. */
14421 if (GET_CODE (addr) == AND)
14423 and_op2 = XEXP (addr, 1);
14424 addr = XEXP (addr, 0);
14427 if (GET_CODE (addr) == PRE_MODIFY)
14429 scratch_or_premodify = XEXP (addr, 0);
14430 gcc_assert (REG_P (scratch_or_premodify));
14431 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14432 addr = XEXP (addr, 1);
14435 if (GET_CODE (addr) == PLUS
14436 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14437 || and_op2 != NULL_RTX))
14439 addr_op1 = XEXP (addr, 0);
14440 addr_op2 = XEXP (addr, 1);
14441 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14443 if (!REG_P (addr_op2)
14444 && (GET_CODE (addr_op2) != CONST_INT
14445 || !satisfies_constraint_I (addr_op2)))
14447 if (TARGET_DEBUG_ADDR)
14450 "\nMove plus addr to register %s, mode = %s: ",
14451 rs6000_reg_names[REGNO (scratch)],
14452 GET_MODE_NAME (mode));
14453 debug_rtx (addr_op2);
14455 rs6000_emit_move (scratch, addr_op2, Pmode);
14456 addr_op2 = scratch;
14459 emit_insn (gen_rtx_SET (VOIDmode,
14460 scratch_or_premodify,
14461 gen_rtx_PLUS (Pmode,
14465 addr = scratch_or_premodify;
14466 scratch_or_premodify = scratch;
14468 else if (!legitimate_indirect_address_p (addr, false)
14469 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14471 if (TARGET_DEBUG_ADDR)
14473 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14474 rs6000_reg_names[REGNO (scratch_or_premodify)],
14475 GET_MODE_NAME (mode));
14478 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14479 addr = scratch_or_premodify;
14480 scratch_or_premodify = scratch;
14484 /* Float/Altivec registers can only handle reg+reg addressing. Move
14485 other addresses into a scratch register. */
14490 /* With float regs, we need to handle the AND ourselves, since we can't
14491 use the Altivec instruction with an implicit AND -16. Allow scalar
14492 loads to float registers to use reg+offset even if VSX. */
14493 if (GET_CODE (addr) == AND
14494 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14495 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14496 || INTVAL (XEXP (addr, 1)) != -16
14497 || !VECTOR_MEM_ALTIVEC_P (mode)))
14499 and_op2 = XEXP (addr, 1);
14500 addr = XEXP (addr, 0);
14503 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14504 as the address later. */
14505 if (GET_CODE (addr) == PRE_MODIFY
14506 && (!VECTOR_MEM_VSX_P (mode)
14507 || and_op2 != NULL_RTX
14508 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14510 scratch_or_premodify = XEXP (addr, 0);
14511 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14513 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14514 addr = XEXP (addr, 1);
14517 if (legitimate_indirect_address_p (addr, false) /* reg */
14518 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14519 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14520 || (GET_CODE (addr) == AND /* Altivec memory */
14521 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14522 && INTVAL (XEXP (addr, 1)) == -16
14523 && VECTOR_MEM_ALTIVEC_P (mode))
14524 || (rclass == FLOAT_REGS /* legacy float mem */
14525 && GET_MODE_SIZE (mode) == 8
14526 && and_op2 == NULL_RTX
14527 && scratch_or_premodify == scratch
14528 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14531 else if (GET_CODE (addr) == PLUS)
14533 addr_op1 = XEXP (addr, 0);
14534 addr_op2 = XEXP (addr, 1);
14535 gcc_assert (REG_P (addr_op1));
14537 if (TARGET_DEBUG_ADDR)
14539 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14540 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14541 debug_rtx (addr_op2);
14543 rs6000_emit_move (scratch, addr_op2, Pmode);
14544 emit_insn (gen_rtx_SET (VOIDmode,
14545 scratch_or_premodify,
14546 gen_rtx_PLUS (Pmode,
14549 addr = scratch_or_premodify;
14550 scratch_or_premodify = scratch;
14553 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14554 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14556 if (TARGET_DEBUG_ADDR)
14558 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14559 rs6000_reg_names[REGNO (scratch_or_premodify)],
14560 GET_MODE_NAME (mode));
14564 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14565 addr = scratch_or_premodify;
14566 scratch_or_premodify = scratch;
14570 gcc_unreachable ();
14575 gcc_unreachable ();
14578 /* If the original address involved a pre-modify that we couldn't use the VSX
14579 memory instruction with update, and we haven't taken care of already,
14580 store the address in the pre-modify register and use that as the
14582 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14584 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14585 addr = scratch_or_premodify;
14588 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14589 memory instruction, recreate the AND now, including the clobber which is
14590 generated by the general ANDSI3/ANDDI3 patterns for the
14591 andi. instruction. */
14592 if (and_op2 != NULL_RTX)
14594 if (! legitimate_indirect_address_p (addr, false))
14596 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14600 if (TARGET_DEBUG_ADDR)
14602 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14603 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14604 debug_rtx (and_op2);
14607 and_rtx = gen_rtx_SET (VOIDmode,
14609 gen_rtx_AND (Pmode,
14613 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14614 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14615 gen_rtvec (2, and_rtx, cc_clobber)));
14619 /* Adjust the address if it changed. */
14620 if (addr != XEXP (mem, 0))
14622 mem = change_address (mem, mode, addr);
14623 if (TARGET_DEBUG_ADDR)
14624 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14627 /* Now create the move. */
14629 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14631 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14636 /* Convert reloads involving 64-bit gprs and misaligned offset
14637 addressing to use indirect addressing. */
14640 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14642 int regno = true_regnum (reg);
14643 enum reg_class rclass;
14645 rtx scratch_or_premodify = scratch;
14647 if (TARGET_DEBUG_ADDR)
14649 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14650 store_p ? "store" : "load");
14651 fprintf (stderr, "reg:\n");
14653 fprintf (stderr, "mem:\n");
14655 fprintf (stderr, "scratch:\n");
14656 debug_rtx (scratch);
14659 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14660 gcc_assert (GET_CODE (mem) == MEM);
14661 rclass = REGNO_REG_CLASS (regno);
14662 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14663 addr = XEXP (mem, 0);
14665 if (GET_CODE (addr) == PRE_MODIFY)
14667 scratch_or_premodify = XEXP (addr, 0);
14668 gcc_assert (REG_P (scratch_or_premodify));
14669 addr = XEXP (addr, 1);
14671 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14673 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14675 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14677 /* Now create the move. */
14679 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14681 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14686 /* Allocate a 64-bit stack slot to be used for copying SDmode
14687 values through if this function has any SDmode references. */
14690 rs6000_alloc_sdmode_stack_slot (void)
14694 gimple_stmt_iterator gsi;
14696 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14699 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14701 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14704 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14705 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14711 /* Check for any SDmode parameters of the function. */
14712 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14714 if (TREE_TYPE (t) == error_mark_node)
14717 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14718 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14720 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14721 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14729 rs6000_instantiate_decls (void)
14731 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14732 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14735 /* Given an rtx X being reloaded into a reg required to be
14736 in class CLASS, return the class of reg to actually use.
14737 In general this is just CLASS; but on some machines
14738 in some cases it is preferable to use a more restrictive class.
14740 On the RS/6000, we have to return NO_REGS when we want to reload a
14741 floating-point CONST_DOUBLE to force it to be copied to memory.
14743 We also don't want to reload integer values into floating-point
14744 registers if we can at all help it. In fact, this can
14745 cause reload to die, if it tries to generate a reload of CTR
14746 into a FP register and discovers it doesn't have the memory location
14749 ??? Would it be a good idea to have reload do the converse, that is
14750 try to reload floating modes into FP registers if possible?
14753 static enum reg_class
14754 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14756 enum machine_mode mode = GET_MODE (x);
14758 if (VECTOR_UNIT_VSX_P (mode)
14759 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14762 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14763 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14764 && easy_vector_constant (x, mode))
14765 return ALTIVEC_REGS;
14767 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14770 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14771 return GENERAL_REGS;
14773 /* For VSX, prefer the traditional registers for 64-bit values because we can
14774 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14775 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14776 prefer Altivec loads.. */
14777 if (rclass == VSX_REGS)
14779 if (GET_MODE_SIZE (mode) <= 8)
14782 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14783 return ALTIVEC_REGS;
14791 /* Debug version of rs6000_preferred_reload_class. */
14792 static enum reg_class
14793 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14795 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14798 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14800 reg_class_names[ret], reg_class_names[rclass],
14801 GET_MODE_NAME (GET_MODE (x)));
14807 /* If we are copying between FP or AltiVec registers and anything else, we need
14808 a memory location. The exception is when we are targeting ppc64 and the
14809 move to/from fpr to gpr instructions are available. Also, under VSX, you
14810 can copy vector registers from the FP register set to the Altivec register
14811 set and vice versa. */
14814 rs6000_secondary_memory_needed (enum reg_class class1,
14815 enum reg_class class2,
14816 enum machine_mode mode)
14818 if (class1 == class2)
14821 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14822 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14823 between these classes. But we need memory for other things that can go in
14824 FLOAT_REGS like SFmode. */
14826 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14827 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14828 || class1 == FLOAT_REGS))
14829 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14830 && class2 != FLOAT_REGS);
14832 if (class1 == VSX_REGS || class2 == VSX_REGS)
14835 if (class1 == FLOAT_REGS
14836 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14837 || ((mode != DFmode)
14838 && (mode != DDmode)
14839 && (mode != DImode))))
14842 if (class2 == FLOAT_REGS
14843 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14844 || ((mode != DFmode)
14845 && (mode != DDmode)
14846 && (mode != DImode))))
14849 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14855 /* Debug version of rs6000_secondary_memory_needed. */
14857 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14858 enum reg_class class2,
14859 enum machine_mode mode)
14861 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14864 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14865 "class2 = %s, mode = %s\n",
14866 ret ? "true" : "false", reg_class_names[class1],
14867 reg_class_names[class2], GET_MODE_NAME (mode));
14872 /* Return the register class of a scratch register needed to copy IN into
14873 or out of a register in RCLASS in MODE. If it can be done directly,
14874 NO_REGS is returned. */
14876 static enum reg_class
14877 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14882 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14884 && MACHOPIC_INDIRECT
14888 /* We cannot copy a symbolic operand directly into anything
14889 other than BASE_REGS for TARGET_ELF. So indicate that a
14890 register from BASE_REGS is needed as an intermediate
14893 On Darwin, pic addresses require a load from memory, which
14894 needs a base register. */
14895 if (rclass != BASE_REGS
14896 && (GET_CODE (in) == SYMBOL_REF
14897 || GET_CODE (in) == HIGH
14898 || GET_CODE (in) == LABEL_REF
14899 || GET_CODE (in) == CONST))
14903 if (GET_CODE (in) == REG)
14905 regno = REGNO (in);
14906 if (regno >= FIRST_PSEUDO_REGISTER)
14908 regno = true_regnum (in);
14909 if (regno >= FIRST_PSEUDO_REGISTER)
14913 else if (GET_CODE (in) == SUBREG)
14915 regno = true_regnum (in);
14916 if (regno >= FIRST_PSEUDO_REGISTER)
14922 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14924 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14925 || (regno >= 0 && INT_REGNO_P (regno)))
14928 /* Constants, memory, and FP registers can go into FP registers. */
14929 if ((regno == -1 || FP_REGNO_P (regno))
14930 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14931 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14933 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14936 && (regno == -1 || VSX_REGNO_P (regno))
14937 && VSX_REG_CLASS_P (rclass))
14940 /* Memory, and AltiVec registers can go into AltiVec registers. */
14941 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14942 && rclass == ALTIVEC_REGS)
14945 /* We can copy among the CR registers. */
14946 if ((rclass == CR_REGS || rclass == CR0_REGS)
14947 && regno >= 0 && CR_REGNO_P (regno))
14950 /* Otherwise, we need GENERAL_REGS. */
14951 return GENERAL_REGS;
14954 /* Debug version of rs6000_secondary_reload_class. */
14955 static enum reg_class
14956 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14957 enum machine_mode mode, rtx in)
14959 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14961 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14962 "mode = %s, input rtx:\n",
14963 reg_class_names[ret], reg_class_names[rclass],
14964 GET_MODE_NAME (mode));
14970 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14973 rs6000_cannot_change_mode_class (enum machine_mode from,
14974 enum machine_mode to,
14975 enum reg_class rclass)
14977 unsigned from_size = GET_MODE_SIZE (from);
14978 unsigned to_size = GET_MODE_SIZE (to);
14980 if (from_size != to_size)
14982 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14983 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14984 && reg_classes_intersect_p (xclass, rclass));
14987 if (TARGET_E500_DOUBLE
14988 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14989 || (((to) == TFmode) + ((from) == TFmode)) == 1
14990 || (((to) == DDmode) + ((from) == DDmode)) == 1
14991 || (((to) == TDmode) + ((from) == TDmode)) == 1
14992 || (((to) == DImode) + ((from) == DImode)) == 1))
14995 /* Since the VSX register set includes traditional floating point registers
14996 and altivec registers, just check for the size being different instead of
14997 trying to check whether the modes are vector modes. Otherwise it won't
14998 allow say DF and DI to change classes. */
14999 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15000 return (from_size != 8 && from_size != 16);
15002 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15003 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15006 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15007 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15013 /* Debug version of rs6000_cannot_change_mode_class. */
15015 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15016 enum machine_mode to,
15017 enum reg_class rclass)
15019 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15022 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15023 "to = %s, rclass = %s\n",
15024 ret ? "true" : "false",
15025 GET_MODE_NAME (from), GET_MODE_NAME (to),
15026 reg_class_names[rclass]);
15031 /* Given a comparison operation, return the bit number in CCR to test. We
15032 know this is a valid comparison.
15034 SCC_P is 1 if this is for an scc. That means that %D will have been
15035 used instead of %C, so the bits will be in different places.
15037 Return -1 if OP isn't a valid comparison for some reason. */
15040 ccr_bit (rtx op, int scc_p)
15042 enum rtx_code code = GET_CODE (op);
15043 enum machine_mode cc_mode;
15048 if (!COMPARISON_P (op))
15051 reg = XEXP (op, 0);
15053 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15055 cc_mode = GET_MODE (reg);
15056 cc_regnum = REGNO (reg);
15057 base_bit = 4 * (cc_regnum - CR0_REGNO);
15059 validate_condition_mode (code, cc_mode);
15061 /* When generating a sCOND operation, only positive conditions are
15064 || code == EQ || code == GT || code == LT || code == UNORDERED
15065 || code == GTU || code == LTU);
15070 return scc_p ? base_bit + 3 : base_bit + 2;
15072 return base_bit + 2;
15073 case GT: case GTU: case UNLE:
15074 return base_bit + 1;
15075 case LT: case LTU: case UNGE:
15077 case ORDERED: case UNORDERED:
15078 return base_bit + 3;
15081 /* If scc, we will have done a cror to put the bit in the
15082 unordered position. So test that bit. For integer, this is ! LT
15083 unless this is an scc insn. */
15084 return scc_p ? base_bit + 3 : base_bit;
15087 return scc_p ? base_bit + 3 : base_bit + 1;
15090 gcc_unreachable ();
15094 /* Return the GOT register. */
15097 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15099 /* The second flow pass currently (June 1999) can't update
15100 regs_ever_live without disturbing other parts of the compiler, so
15101 update it here to make the prolog/epilogue code happy. */
15102 if (!can_create_pseudo_p ()
15103 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15104 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15106 crtl->uses_pic_offset_table = 1;
15108 return pic_offset_table_rtx;
15111 static rs6000_stack_t stack_info;
15113 /* Function to init struct machine_function.
15114 This will be called, via a pointer variable,
15115 from push_function_context. */
15117 static struct machine_function *
15118 rs6000_init_machine_status (void)
15120 stack_info.reload_completed = 0;
15121 return ggc_alloc_cleared_machine_function ();
15124 /* These macros test for integers and extract the low-order bits. */
15126 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15127 && GET_MODE (X) == VOIDmode)
15129 #define INT_LOWPART(X) \
15130 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15133 extract_MB (rtx op)
15136 unsigned long val = INT_LOWPART (op);
15138 /* If the high bit is zero, the value is the first 1 bit we find
15140 if ((val & 0x80000000) == 0)
15142 gcc_assert (val & 0xffffffff);
15145 while (((val <<= 1) & 0x80000000) == 0)
15150 /* If the high bit is set and the low bit is not, or the mask is all
15151 1's, the value is zero. */
15152 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15155 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15158 while (((val >>= 1) & 1) != 0)
15165 extract_ME (rtx op)
15168 unsigned long val = INT_LOWPART (op);
15170 /* If the low bit is zero, the value is the first 1 bit we find from
15172 if ((val & 1) == 0)
15174 gcc_assert (val & 0xffffffff);
15177 while (((val >>= 1) & 1) == 0)
15183 /* If the low bit is set and the high bit is not, or the mask is all
15184 1's, the value is 31. */
15185 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15188 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15191 while (((val <<= 1) & 0x80000000) != 0)
15197 /* Locate some local-dynamic symbol still in use by this function
15198 so that we can print its name in some tls_ld pattern. */
15200 static const char *
15201 rs6000_get_some_local_dynamic_name (void)
15205 if (cfun->machine->some_ld_name)
15206 return cfun->machine->some_ld_name;
15208 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15210 && for_each_rtx (&PATTERN (insn),
15211 rs6000_get_some_local_dynamic_name_1, 0))
15212 return cfun->machine->some_ld_name;
15214 gcc_unreachable ();
15217 /* Helper function for rs6000_get_some_local_dynamic_name. */
15220 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15224 if (GET_CODE (x) == SYMBOL_REF)
15226 const char *str = XSTR (x, 0);
15227 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15229 cfun->machine->some_ld_name = str;
15237 /* Write out a function code label. */
15240 rs6000_output_function_entry (FILE *file, const char *fname)
15242 if (fname[0] != '.')
15244 switch (DEFAULT_ABI)
15247 gcc_unreachable ();
15253 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15262 RS6000_OUTPUT_BASENAME (file, fname);
15265 /* Print an operand. Recognize special options, documented below. */
15268 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15269 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15271 #define SMALL_DATA_RELOC "sda21"
15272 #define SMALL_DATA_REG 0
15276 print_operand (FILE *file, rtx x, int code)
15280 unsigned HOST_WIDE_INT uval;
15285 /* Write out an instruction after the call which may be replaced
15286 with glue code by the loader. This depends on the AIX version. */
15287 asm_fprintf (file, RS6000_CALL_GLUE);
15290 /* %a is output_address. */
15293 /* If X is a constant integer whose low-order 5 bits are zero,
15294 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15295 in the AIX assembler where "sri" with a zero shift count
15296 writes a trash instruction. */
15297 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15304 /* If constant, low-order 16 bits of constant, unsigned.
15305 Otherwise, write normally. */
15307 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15309 print_operand (file, x, 0);
15313 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15314 for 64-bit mask direction. */
15315 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15318 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15322 /* X is a CR register. Print the number of the GT bit of the CR. */
15323 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15324 output_operand_lossage ("invalid %%c value");
15326 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15330 /* Like 'J' but get to the GT bit only. */
15331 gcc_assert (GET_CODE (x) == REG);
15333 /* Bit 1 is GT bit. */
15334 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15336 /* Add one for shift count in rlinm for scc. */
15337 fprintf (file, "%d", i + 1);
15341 /* X is a CR register. Print the number of the EQ bit of the CR */
15342 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15343 output_operand_lossage ("invalid %%E value");
15345 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15349 /* X is a CR register. Print the shift count needed to move it
15350 to the high-order four bits. */
15351 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15352 output_operand_lossage ("invalid %%f value");
15354 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15358 /* Similar, but print the count for the rotate in the opposite
15360 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15361 output_operand_lossage ("invalid %%F value");
15363 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15367 /* X is a constant integer. If it is negative, print "m",
15368 otherwise print "z". This is to make an aze or ame insn. */
15369 if (GET_CODE (x) != CONST_INT)
15370 output_operand_lossage ("invalid %%G value");
15371 else if (INTVAL (x) >= 0)
15378 /* If constant, output low-order five bits. Otherwise, write
15381 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15383 print_operand (file, x, 0);
15387 /* If constant, output low-order six bits. Otherwise, write
15390 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15392 print_operand (file, x, 0);
15396 /* Print `i' if this is a constant, else nothing. */
15402 /* Write the bit number in CCR for jump. */
15403 i = ccr_bit (x, 0);
15405 output_operand_lossage ("invalid %%j code");
15407 fprintf (file, "%d", i);
15411 /* Similar, but add one for shift count in rlinm for scc and pass
15412 scc flag to `ccr_bit'. */
15413 i = ccr_bit (x, 1);
15415 output_operand_lossage ("invalid %%J code");
15417 /* If we want bit 31, write a shift count of zero, not 32. */
15418 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15422 /* X must be a constant. Write the 1's complement of the
15425 output_operand_lossage ("invalid %%k value");
15427 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15431 /* X must be a symbolic constant on ELF. Write an
15432 expression suitable for an 'addi' that adds in the low 16
15433 bits of the MEM. */
15434 if (GET_CODE (x) == CONST)
15436 if (GET_CODE (XEXP (x, 0)) != PLUS
15437 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15438 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15439 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15440 output_operand_lossage ("invalid %%K value");
15442 print_operand_address (file, x);
15443 fputs ("@l", file);
15446 /* %l is output_asm_label. */
15449 /* Write second word of DImode or DFmode reference. Works on register
15450 or non-indexed memory only. */
15451 if (GET_CODE (x) == REG)
15452 fputs (reg_names[REGNO (x) + 1], file);
15453 else if (GET_CODE (x) == MEM)
15455 /* Handle possible auto-increment. Since it is pre-increment and
15456 we have already done it, we can just use an offset of word. */
15457 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15458 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15459 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15461 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15462 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15465 output_address (XEXP (adjust_address_nv (x, SImode,
15469 if (small_data_operand (x, GET_MODE (x)))
15470 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15471 reg_names[SMALL_DATA_REG]);
15476 /* MB value for a mask operand. */
15477 if (! mask_operand (x, SImode))
15478 output_operand_lossage ("invalid %%m value");
15480 fprintf (file, "%d", extract_MB (x));
15484 /* ME value for a mask operand. */
15485 if (! mask_operand (x, SImode))
15486 output_operand_lossage ("invalid %%M value");
15488 fprintf (file, "%d", extract_ME (x));
15491 /* %n outputs the negative of its operand. */
15494 /* Write the number of elements in the vector times 4. */
15495 if (GET_CODE (x) != PARALLEL)
15496 output_operand_lossage ("invalid %%N value");
15498 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15502 /* Similar, but subtract 1 first. */
15503 if (GET_CODE (x) != PARALLEL)
15504 output_operand_lossage ("invalid %%O value");
15506 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15510 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15512 || INT_LOWPART (x) < 0
15513 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15514 output_operand_lossage ("invalid %%p value");
15516 fprintf (file, "%d", i);
15520 /* The operand must be an indirect memory reference. The result
15521 is the register name. */
15522 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15523 || REGNO (XEXP (x, 0)) >= 32)
15524 output_operand_lossage ("invalid %%P value");
15526 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15530 /* This outputs the logical code corresponding to a boolean
15531 expression. The expression may have one or both operands
15532 negated (if one, only the first one). For condition register
15533 logical operations, it will also treat the negated
15534 CR codes as NOTs, but not handle NOTs of them. */
15536 const char *const *t = 0;
15538 enum rtx_code code = GET_CODE (x);
15539 static const char * const tbl[3][3] = {
15540 { "and", "andc", "nor" },
15541 { "or", "orc", "nand" },
15542 { "xor", "eqv", "xor" } };
15546 else if (code == IOR)
15548 else if (code == XOR)
15551 output_operand_lossage ("invalid %%q value");
15553 if (GET_CODE (XEXP (x, 0)) != NOT)
15557 if (GET_CODE (XEXP (x, 1)) == NOT)
15575 /* X is a CR register. Print the mask for `mtcrf'. */
15576 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15577 output_operand_lossage ("invalid %%R value");
15579 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15583 /* Low 5 bits of 32 - value */
15585 output_operand_lossage ("invalid %%s value");
15587 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15591 /* PowerPC64 mask position. All 0's is excluded.
15592 CONST_INT 32-bit mask is considered sign-extended so any
15593 transition must occur within the CONST_INT, not on the boundary. */
15594 if (! mask64_operand (x, DImode))
15595 output_operand_lossage ("invalid %%S value");
15597 uval = INT_LOWPART (x);
15599 if (uval & 1) /* Clear Left */
15601 #if HOST_BITS_PER_WIDE_INT > 64
15602 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15606 else /* Clear Right */
15609 #if HOST_BITS_PER_WIDE_INT > 64
15610 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15616 gcc_assert (i >= 0);
15617 fprintf (file, "%d", i);
15621 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15622 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15624 /* Bit 3 is OV bit. */
15625 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15627 /* If we want bit 31, write a shift count of zero, not 32. */
15628 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15632 /* Print the symbolic name of a branch target register. */
15633 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15634 && REGNO (x) != CTR_REGNO))
15635 output_operand_lossage ("invalid %%T value");
15636 else if (REGNO (x) == LR_REGNO)
15637 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15639 fputs ("ctr", file);
15643 /* High-order 16 bits of constant for use in unsigned operand. */
15645 output_operand_lossage ("invalid %%u value");
15647 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15648 (INT_LOWPART (x) >> 16) & 0xffff);
15652 /* High-order 16 bits of constant for use in signed operand. */
15654 output_operand_lossage ("invalid %%v value");
15656 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15657 (INT_LOWPART (x) >> 16) & 0xffff);
15661 /* Print `u' if this has an auto-increment or auto-decrement. */
15662 if (GET_CODE (x) == MEM
15663 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15664 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15665 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15670 /* Print the trap code for this operand. */
15671 switch (GET_CODE (x))
15674 fputs ("eq", file); /* 4 */
15677 fputs ("ne", file); /* 24 */
15680 fputs ("lt", file); /* 16 */
15683 fputs ("le", file); /* 20 */
15686 fputs ("gt", file); /* 8 */
15689 fputs ("ge", file); /* 12 */
15692 fputs ("llt", file); /* 2 */
15695 fputs ("lle", file); /* 6 */
15698 fputs ("lgt", file); /* 1 */
15701 fputs ("lge", file); /* 5 */
15704 gcc_unreachable ();
15709 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15712 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15713 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15715 print_operand (file, x, 0);
15719 /* MB value for a PowerPC64 rldic operand. */
15720 val = (GET_CODE (x) == CONST_INT
15721 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15726 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15727 if ((val <<= 1) < 0)
15730 #if HOST_BITS_PER_WIDE_INT == 32
15731 if (GET_CODE (x) == CONST_INT && i >= 0)
15732 i += 32; /* zero-extend high-part was all 0's */
15733 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15735 val = CONST_DOUBLE_LOW (x);
15741 for ( ; i < 64; i++)
15742 if ((val <<= 1) < 0)
15747 fprintf (file, "%d", i + 1);
15751 /* X is a FPR or Altivec register used in a VSX context. */
15752 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15753 output_operand_lossage ("invalid %%x value");
15756 int reg = REGNO (x);
15757 int vsx_reg = (FP_REGNO_P (reg)
15759 : reg - FIRST_ALTIVEC_REGNO + 32);
15761 #ifdef TARGET_REGNAMES
15762 if (TARGET_REGNAMES)
15763 fprintf (file, "%%vs%d", vsx_reg);
15766 fprintf (file, "%d", vsx_reg);
15771 if (GET_CODE (x) == MEM
15772 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15773 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15774 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15779 /* Like 'L', for third word of TImode */
15780 if (GET_CODE (x) == REG)
15781 fputs (reg_names[REGNO (x) + 2], file);
15782 else if (GET_CODE (x) == MEM)
15784 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15785 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15786 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15787 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15788 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15790 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15791 if (small_data_operand (x, GET_MODE (x)))
15792 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15793 reg_names[SMALL_DATA_REG]);
15798 /* X is a SYMBOL_REF. Write out the name preceded by a
15799 period and without any trailing data in brackets. Used for function
15800 names. If we are configured for System V (or the embedded ABI) on
15801 the PowerPC, do not emit the period, since those systems do not use
15802 TOCs and the like. */
15803 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15805 /* Mark the decl as referenced so that cgraph will output the
15807 if (SYMBOL_REF_DECL (x))
15808 mark_decl_referenced (SYMBOL_REF_DECL (x));
15810 /* For macho, check to see if we need a stub. */
15813 const char *name = XSTR (x, 0);
15815 if (darwin_emit_branch_islands
15816 && MACHOPIC_INDIRECT
15817 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15818 name = machopic_indirection_name (x, /*stub_p=*/true);
15820 assemble_name (file, name);
15822 else if (!DOT_SYMBOLS)
15823 assemble_name (file, XSTR (x, 0));
15825 rs6000_output_function_entry (file, XSTR (x, 0));
15829 /* Like 'L', for last word of TImode. */
15830 if (GET_CODE (x) == REG)
15831 fputs (reg_names[REGNO (x) + 3], file);
15832 else if (GET_CODE (x) == MEM)
15834 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15835 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15836 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15837 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15838 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15840 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15841 if (small_data_operand (x, GET_MODE (x)))
15842 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15843 reg_names[SMALL_DATA_REG]);
15847 /* Print AltiVec or SPE memory operand. */
15852 gcc_assert (GET_CODE (x) == MEM);
15856 /* Ugly hack because %y is overloaded. */
15857 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15858 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15859 || GET_MODE (x) == TFmode
15860 || GET_MODE (x) == TImode))
15862 /* Handle [reg]. */
15863 if (GET_CODE (tmp) == REG)
15865 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15868 /* Handle [reg+UIMM]. */
15869 else if (GET_CODE (tmp) == PLUS &&
15870 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15874 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15876 x = INTVAL (XEXP (tmp, 1));
15877 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15881 /* Fall through. Must be [reg+reg]. */
15883 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15884 && GET_CODE (tmp) == AND
15885 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15886 && INTVAL (XEXP (tmp, 1)) == -16)
15887 tmp = XEXP (tmp, 0);
15888 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15889 && GET_CODE (tmp) == PRE_MODIFY)
15890 tmp = XEXP (tmp, 1);
15891 if (GET_CODE (tmp) == REG)
15892 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15895 if (!GET_CODE (tmp) == PLUS
15896 || !REG_P (XEXP (tmp, 0))
15897 || !REG_P (XEXP (tmp, 1)))
15899 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15903 if (REGNO (XEXP (tmp, 0)) == 0)
15904 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15905 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15907 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15908 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15914 if (GET_CODE (x) == REG)
15915 fprintf (file, "%s", reg_names[REGNO (x)]);
15916 else if (GET_CODE (x) == MEM)
15918 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15919 know the width from the mode. */
15920 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15921 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15922 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15923 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15924 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15925 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15926 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15927 output_address (XEXP (XEXP (x, 0), 1));
15929 output_address (XEXP (x, 0));
15933 if (toc_relative_expr_p (x))
15934 /* This hack along with a corresponding hack in
15935 rs6000_output_addr_const_extra arranges to output addends
15936 where the assembler expects to find them. eg.
15937 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15938 without this hack would be output as "x@toc+4". We
15940 output_addr_const (file, tocrel_base);
15942 output_addr_const (file, x);
15947 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15951 output_operand_lossage ("invalid %%xn code");
15955 /* Print the address of an operand. */
15958 print_operand_address (FILE *file, rtx x)
15960 if (GET_CODE (x) == REG)
15961 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15962 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15963 || GET_CODE (x) == LABEL_REF)
15965 output_addr_const (file, x);
15966 if (small_data_operand (x, GET_MODE (x)))
15967 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15968 reg_names[SMALL_DATA_REG]);
15970 gcc_assert (!TARGET_TOC);
15972 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15974 gcc_assert (REG_P (XEXP (x, 0)));
15975 if (REGNO (XEXP (x, 0)) == 0)
15976 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15977 reg_names[ REGNO (XEXP (x, 0)) ]);
15979 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15980 reg_names[ REGNO (XEXP (x, 1)) ]);
15982 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15983 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15984 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15986 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15987 && CONSTANT_P (XEXP (x, 1)))
15989 fprintf (file, "lo16(");
15990 output_addr_const (file, XEXP (x, 1));
15991 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15994 else if (legitimate_constant_pool_address_p (x, QImode, true))
15996 /* This hack along with a corresponding hack in
15997 rs6000_output_addr_const_extra arranges to output addends
15998 where the assembler expects to find them. eg.
16000 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16001 without this hack would be output as "x@toc+8@l(9)". We
16002 want "x+8@toc@l(9)". */
16003 output_addr_const (file, tocrel_base);
16004 if (GET_CODE (x) == LO_SUM)
16005 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16007 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16010 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16011 && CONSTANT_P (XEXP (x, 1)))
16013 output_addr_const (file, XEXP (x, 1));
16014 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16018 gcc_unreachable ();
16021 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16024 rs6000_output_addr_const_extra (FILE *file, rtx x)
16026 if (GET_CODE (x) == UNSPEC)
16027 switch (XINT (x, 1))
16029 case UNSPEC_TOCREL:
16030 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16031 output_addr_const (file, XVECEXP (x, 0, 0));
16032 if (x == tocrel_base && tocrel_offset != const0_rtx)
16034 if (INTVAL (tocrel_offset) >= 0)
16035 fprintf (file, "+");
16036 output_addr_const (file, tocrel_offset);
16038 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16041 assemble_name (file, toc_label_name);
16043 else if (TARGET_ELF)
16044 fputs ("@toc", file);
16048 case UNSPEC_MACHOPIC_OFFSET:
16049 output_addr_const (file, XVECEXP (x, 0, 0));
16051 machopic_output_function_base_name (file);
16058 /* Target hook for assembling integer objects. The PowerPC version has
16059 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16060 is defined. It also needs to handle DI-mode objects on 64-bit
16064 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16066 #ifdef RELOCATABLE_NEEDS_FIXUP
16067 /* Special handling for SI values. */
16068 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16070 static int recurse = 0;
16072 /* For -mrelocatable, we mark all addresses that need to be fixed up
16073 in the .fixup section. */
16074 if (TARGET_RELOCATABLE
16075 && in_section != toc_section
16076 && in_section != text_section
16077 && !unlikely_text_section_p (in_section)
16079 && GET_CODE (x) != CONST_INT
16080 && GET_CODE (x) != CONST_DOUBLE
16086 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16088 ASM_OUTPUT_LABEL (asm_out_file, buf);
16089 fprintf (asm_out_file, "\t.long\t(");
16090 output_addr_const (asm_out_file, x);
16091 fprintf (asm_out_file, ")@fixup\n");
16092 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16093 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16094 fprintf (asm_out_file, "\t.long\t");
16095 assemble_name (asm_out_file, buf);
16096 fprintf (asm_out_file, "\n\t.previous\n");
16100 /* Remove initial .'s to turn a -mcall-aixdesc function
16101 address into the address of the descriptor, not the function
16103 else if (GET_CODE (x) == SYMBOL_REF
16104 && XSTR (x, 0)[0] == '.'
16105 && DEFAULT_ABI == ABI_AIX)
16107 const char *name = XSTR (x, 0);
16108 while (*name == '.')
16111 fprintf (asm_out_file, "\t.long\t%s\n", name);
16115 #endif /* RELOCATABLE_NEEDS_FIXUP */
16116 return default_assemble_integer (x, size, aligned_p);
16119 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16120 /* Emit an assembler directive to set symbol visibility for DECL to
16121 VISIBILITY_TYPE. */
16124 rs6000_assemble_visibility (tree decl, int vis)
16126 /* Functions need to have their entry point symbol visibility set as
16127 well as their descriptor symbol visibility. */
16128 if (DEFAULT_ABI == ABI_AIX
16130 && TREE_CODE (decl) == FUNCTION_DECL)
16132 static const char * const visibility_types[] = {
16133 NULL, "internal", "hidden", "protected"
16136 const char *name, *type;
16138 name = ((* targetm.strip_name_encoding)
16139 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16140 type = visibility_types[vis];
16142 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16143 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16146 default_assemble_visibility (decl, vis);
16151 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16153 /* Reversal of FP compares takes care -- an ordered compare
16154 becomes an unordered compare and vice versa. */
16155 if (mode == CCFPmode
16156 && (!flag_finite_math_only
16157 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16158 || code == UNEQ || code == LTGT))
16159 return reverse_condition_maybe_unordered (code);
16161 return reverse_condition (code);
16164 /* Generate a compare for CODE. Return a brand-new rtx that
16165 represents the result of the compare. */
16168 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16170 enum machine_mode comp_mode;
16171 rtx compare_result;
16172 enum rtx_code code = GET_CODE (cmp);
16173 rtx op0 = XEXP (cmp, 0);
16174 rtx op1 = XEXP (cmp, 1);
16176 if (FLOAT_MODE_P (mode))
16177 comp_mode = CCFPmode;
16178 else if (code == GTU || code == LTU
16179 || code == GEU || code == LEU)
16180 comp_mode = CCUNSmode;
16181 else if ((code == EQ || code == NE)
16182 && GET_CODE (op0) == SUBREG
16183 && GET_CODE (op1) == SUBREG
16184 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16185 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16186 /* These are unsigned values, perhaps there will be a later
16187 ordering compare that can be shared with this one.
16188 Unfortunately we cannot detect the signedness of the operands
16189 for non-subregs. */
16190 comp_mode = CCUNSmode;
16192 comp_mode = CCmode;
16194 /* First, the compare. */
16195 compare_result = gen_reg_rtx (comp_mode);
16197 /* E500 FP compare instructions on the GPRs. Yuck! */
16198 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16199 && FLOAT_MODE_P (mode))
16201 rtx cmp, or_result, compare_result2;
16202 enum machine_mode op_mode = GET_MODE (op0);
16204 if (op_mode == VOIDmode)
16205 op_mode = GET_MODE (op1);
16207 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16208 This explains the following mess. */
16212 case EQ: case UNEQ: case NE: case LTGT:
16216 cmp = (flag_finite_math_only && !flag_trapping_math)
16217 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16218 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16222 cmp = (flag_finite_math_only && !flag_trapping_math)
16223 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16224 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16228 cmp = (flag_finite_math_only && !flag_trapping_math)
16229 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16230 : gen_cmptfeq_gpr (compare_result, op0, op1);
16234 gcc_unreachable ();
16238 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16242 cmp = (flag_finite_math_only && !flag_trapping_math)
16243 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16244 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16248 cmp = (flag_finite_math_only && !flag_trapping_math)
16249 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16250 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16254 cmp = (flag_finite_math_only && !flag_trapping_math)
16255 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16256 : gen_cmptfgt_gpr (compare_result, op0, op1);
16260 gcc_unreachable ();
16264 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16268 cmp = (flag_finite_math_only && !flag_trapping_math)
16269 ? gen_tstsflt_gpr (compare_result, op0, op1)
16270 : gen_cmpsflt_gpr (compare_result, op0, op1);
16274 cmp = (flag_finite_math_only && !flag_trapping_math)
16275 ? gen_tstdflt_gpr (compare_result, op0, op1)
16276 : gen_cmpdflt_gpr (compare_result, op0, op1);
16280 cmp = (flag_finite_math_only && !flag_trapping_math)
16281 ? gen_tsttflt_gpr (compare_result, op0, op1)
16282 : gen_cmptflt_gpr (compare_result, op0, op1);
16286 gcc_unreachable ();
16290 gcc_unreachable ();
16293 /* Synthesize LE and GE from LT/GT || EQ. */
16294 if (code == LE || code == GE || code == LEU || code == GEU)
16300 case LE: code = LT; break;
16301 case GE: code = GT; break;
16302 case LEU: code = LT; break;
16303 case GEU: code = GT; break;
16304 default: gcc_unreachable ();
16307 compare_result2 = gen_reg_rtx (CCFPmode);
16313 cmp = (flag_finite_math_only && !flag_trapping_math)
16314 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16315 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16319 cmp = (flag_finite_math_only && !flag_trapping_math)
16320 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16321 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16325 cmp = (flag_finite_math_only && !flag_trapping_math)
16326 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16327 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16331 gcc_unreachable ();
16335 /* OR them together. */
16336 or_result = gen_reg_rtx (CCFPmode);
16337 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16339 compare_result = or_result;
16344 if (code == NE || code == LTGT)
16354 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16355 CLOBBERs to match cmptf_internal2 pattern. */
16356 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16357 && GET_MODE (op0) == TFmode
16358 && !TARGET_IEEEQUAD
16359 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16360 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16362 gen_rtx_SET (VOIDmode,
16364 gen_rtx_COMPARE (comp_mode, op0, op1)),
16365 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16366 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16367 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16368 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16369 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16370 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16371 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16372 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16373 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16374 else if (GET_CODE (op1) == UNSPEC
16375 && XINT (op1, 1) == UNSPEC_SP_TEST)
16377 rtx op1b = XVECEXP (op1, 0, 0);
16378 comp_mode = CCEQmode;
16379 compare_result = gen_reg_rtx (CCEQmode);
16381 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16383 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16386 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16387 gen_rtx_COMPARE (comp_mode, op0, op1)));
16390 /* Some kinds of FP comparisons need an OR operation;
16391 under flag_finite_math_only we don't bother. */
16392 if (FLOAT_MODE_P (mode)
16393 && !flag_finite_math_only
16394 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16395 && (code == LE || code == GE
16396 || code == UNEQ || code == LTGT
16397 || code == UNGT || code == UNLT))
16399 enum rtx_code or1, or2;
16400 rtx or1_rtx, or2_rtx, compare2_rtx;
16401 rtx or_result = gen_reg_rtx (CCEQmode);
16405 case LE: or1 = LT; or2 = EQ; break;
16406 case GE: or1 = GT; or2 = EQ; break;
16407 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16408 case LTGT: or1 = LT; or2 = GT; break;
16409 case UNGT: or1 = UNORDERED; or2 = GT; break;
16410 case UNLT: or1 = UNORDERED; or2 = LT; break;
16411 default: gcc_unreachable ();
16413 validate_condition_mode (or1, comp_mode);
16414 validate_condition_mode (or2, comp_mode);
16415 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16416 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16417 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16418 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16420 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16422 compare_result = or_result;
16426 validate_condition_mode (code, GET_MODE (compare_result));
16428 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16432 /* Emit the RTL for an sISEL pattern. */
16435 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16437 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16441 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16444 enum machine_mode op_mode;
16445 enum rtx_code cond_code;
16446 rtx result = operands[0];
16448 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16450 rs6000_emit_sISEL (mode, operands);
16454 condition_rtx = rs6000_generate_compare (operands[1], mode);
16455 cond_code = GET_CODE (condition_rtx);
16457 if (FLOAT_MODE_P (mode)
16458 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16462 PUT_MODE (condition_rtx, SImode);
16463 t = XEXP (condition_rtx, 0);
16465 gcc_assert (cond_code == NE || cond_code == EQ);
16467 if (cond_code == NE)
16468 emit_insn (gen_e500_flip_gt_bit (t, t));
16470 emit_insn (gen_move_from_CR_gt_bit (result, t));
16474 if (cond_code == NE
16475 || cond_code == GE || cond_code == LE
16476 || cond_code == GEU || cond_code == LEU
16477 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16479 rtx not_result = gen_reg_rtx (CCEQmode);
16480 rtx not_op, rev_cond_rtx;
16481 enum machine_mode cc_mode;
16483 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16485 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16486 SImode, XEXP (condition_rtx, 0), const0_rtx);
16487 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16488 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16489 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16492 op_mode = GET_MODE (XEXP (operands[1], 0));
16493 if (op_mode == VOIDmode)
16494 op_mode = GET_MODE (XEXP (operands[1], 1));
16496 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16498 PUT_MODE (condition_rtx, DImode);
16499 convert_move (result, condition_rtx, 0);
16503 PUT_MODE (condition_rtx, SImode);
16504 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16508 /* Emit a branch of kind CODE to location LOC. */
16511 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16513 rtx condition_rtx, loc_ref;
16515 condition_rtx = rs6000_generate_compare (operands[0], mode);
16516 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16517 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16518 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16519 loc_ref, pc_rtx)));
16522 /* Return the string to output a conditional branch to LABEL, which is
16523 the operand number of the label, or -1 if the branch is really a
16524 conditional return.
16526 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16527 condition code register and its mode specifies what kind of
16528 comparison we made.
16530 REVERSED is nonzero if we should reverse the sense of the comparison.
16532 INSN is the insn. */
16535 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16537 static char string[64];
16538 enum rtx_code code = GET_CODE (op);
16539 rtx cc_reg = XEXP (op, 0);
16540 enum machine_mode mode = GET_MODE (cc_reg);
16541 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16542 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16543 int really_reversed = reversed ^ need_longbranch;
16549 validate_condition_mode (code, mode);
16551 /* Work out which way this really branches. We could use
16552 reverse_condition_maybe_unordered here always but this
16553 makes the resulting assembler clearer. */
16554 if (really_reversed)
16556 /* Reversal of FP compares takes care -- an ordered compare
16557 becomes an unordered compare and vice versa. */
16558 if (mode == CCFPmode)
16559 code = reverse_condition_maybe_unordered (code);
16561 code = reverse_condition (code);
16564 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16566 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16571 /* Opposite of GT. */
16580 gcc_unreachable ();
16586 /* Not all of these are actually distinct opcodes, but
16587 we distinguish them for clarity of the resulting assembler. */
16588 case NE: case LTGT:
16589 ccode = "ne"; break;
16590 case EQ: case UNEQ:
16591 ccode = "eq"; break;
16593 ccode = "ge"; break;
16594 case GT: case GTU: case UNGT:
16595 ccode = "gt"; break;
16597 ccode = "le"; break;
16598 case LT: case LTU: case UNLT:
16599 ccode = "lt"; break;
16600 case UNORDERED: ccode = "un"; break;
16601 case ORDERED: ccode = "nu"; break;
16602 case UNGE: ccode = "nl"; break;
16603 case UNLE: ccode = "ng"; break;
16605 gcc_unreachable ();
16608 /* Maybe we have a guess as to how likely the branch is.
16609 The old mnemonics don't have a way to specify this information. */
16611 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16612 if (note != NULL_RTX)
16614 /* PROB is the difference from 50%. */
16615 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16617 /* Only hint for highly probable/improbable branches on newer
16618 cpus as static prediction overrides processor dynamic
16619 prediction. For older cpus we may as well always hint, but
16620 assume not taken for branches that are very close to 50% as a
16621 mispredicted taken branch is more expensive than a
16622 mispredicted not-taken branch. */
16623 if (rs6000_always_hint
16624 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16625 && br_prob_note_reliable_p (note)))
16627 if (abs (prob) > REG_BR_PROB_BASE / 20
16628 && ((prob > 0) ^ need_longbranch))
16636 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16638 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16640 /* We need to escape any '%' characters in the reg_names string.
16641 Assume they'd only be the first character.... */
16642 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16644 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16648 /* If the branch distance was too far, we may have to use an
16649 unconditional branch to go the distance. */
16650 if (need_longbranch)
16651 s += sprintf (s, ",$+8\n\tb %s", label);
16653 s += sprintf (s, ",%s", label);
16659 /* Return the string to flip the GT bit on a CR. */
16661 output_e500_flip_gt_bit (rtx dst, rtx src)
16663 static char string[64];
16666 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16667 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16670 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16671 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16673 sprintf (string, "crnot %d,%d", a, b);
16677 /* Return insn for VSX or Altivec comparisons. */
16680 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16683 enum machine_mode mode = GET_MODE (op0);
16691 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16697 mask = gen_reg_rtx (mode);
16698 emit_insn (gen_rtx_SET (VOIDmode,
16700 gen_rtx_fmt_ee (code, mode, op0, op1)));
16707 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16708 DMODE is expected destination mode. This is a recursive function. */
16711 rs6000_emit_vector_compare (enum rtx_code rcode,
16713 enum machine_mode dmode)
16716 bool swap_operands = false;
16717 bool try_again = false;
16719 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16720 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16722 /* See if the comparison works as is. */
16723 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16731 swap_operands = true;
16736 swap_operands = true;
16744 /* Invert condition and try again.
16745 e.g., A != B becomes ~(A==B). */
16747 enum rtx_code rev_code;
16748 enum insn_code nor_code;
16751 rev_code = reverse_condition_maybe_unordered (rcode);
16752 if (rev_code == UNKNOWN)
16755 nor_code = optab_handler (one_cmpl_optab, dmode);
16756 if (nor_code == CODE_FOR_nothing)
16759 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16763 mask = gen_reg_rtx (dmode);
16764 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16772 /* Try GT/GTU/LT/LTU OR EQ */
16775 enum insn_code ior_code;
16776 enum rtx_code new_code;
16797 gcc_unreachable ();
16800 ior_code = optab_handler (ior_optab, dmode);
16801 if (ior_code == CODE_FOR_nothing)
16804 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16808 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16812 mask = gen_reg_rtx (dmode);
16813 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16831 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16836 /* You only get two chances. */
16840 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16841 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16842 operands for the relation operation COND. */
16845 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16846 rtx cond, rtx cc_op0, rtx cc_op1)
16848 enum machine_mode dest_mode = GET_MODE (dest);
16849 enum rtx_code rcode = GET_CODE (cond);
16850 enum machine_mode cc_mode = CCmode;
16854 bool invert_move = false;
16856 if (VECTOR_UNIT_NONE_P (dest_mode))
16861 /* Swap operands if we can, and fall back to doing the operation as
16862 specified, and doing a NOR to invert the test. */
16868 /* Invert condition and try again.
16869 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16870 invert_move = true;
16871 rcode = reverse_condition_maybe_unordered (rcode);
16872 if (rcode == UNKNOWN)
16876 /* Mark unsigned tests with CCUNSmode. */
16881 cc_mode = CCUNSmode;
16888 /* Get the vector mask for the given relational operations. */
16889 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16897 op_true = op_false;
16901 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16902 emit_insn (gen_rtx_SET (VOIDmode,
16904 gen_rtx_IF_THEN_ELSE (dest_mode,
16911 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16912 operands of the last comparison is nonzero/true, FALSE_COND if it
16913 is zero/false. Return 0 if the hardware has no such operation. */
16916 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16918 enum rtx_code code = GET_CODE (op);
16919 rtx op0 = XEXP (op, 0);
16920 rtx op1 = XEXP (op, 1);
16921 REAL_VALUE_TYPE c1;
16922 enum machine_mode compare_mode = GET_MODE (op0);
16923 enum machine_mode result_mode = GET_MODE (dest);
16925 bool is_against_zero;
16927 /* These modes should always match. */
16928 if (GET_MODE (op1) != compare_mode
16929 /* In the isel case however, we can use a compare immediate, so
16930 op1 may be a small constant. */
16931 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16933 if (GET_MODE (true_cond) != result_mode)
16935 if (GET_MODE (false_cond) != result_mode)
16938 /* First, work out if the hardware can do this at all, or
16939 if it's too slow.... */
16940 if (!FLOAT_MODE_P (compare_mode))
16943 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16946 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16947 && SCALAR_FLOAT_MODE_P (compare_mode))
16950 is_against_zero = op1 == CONST0_RTX (compare_mode);
16952 /* A floating-point subtract might overflow, underflow, or produce
16953 an inexact result, thus changing the floating-point flags, so it
16954 can't be generated if we care about that. It's safe if one side
16955 of the construct is zero, since then no subtract will be
16957 if (SCALAR_FLOAT_MODE_P (compare_mode)
16958 && flag_trapping_math && ! is_against_zero)
16961 /* Eliminate half of the comparisons by switching operands, this
16962 makes the remaining code simpler. */
16963 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16964 || code == LTGT || code == LT || code == UNLE)
16966 code = reverse_condition_maybe_unordered (code);
16968 true_cond = false_cond;
16972 /* UNEQ and LTGT take four instructions for a comparison with zero,
16973 it'll probably be faster to use a branch here too. */
16974 if (code == UNEQ && HONOR_NANS (compare_mode))
16977 if (GET_CODE (op1) == CONST_DOUBLE)
16978 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16980 /* We're going to try to implement comparisons by performing
16981 a subtract, then comparing against zero. Unfortunately,
16982 Inf - Inf is NaN which is not zero, and so if we don't
16983 know that the operand is finite and the comparison
16984 would treat EQ different to UNORDERED, we can't do it. */
16985 if (HONOR_INFINITIES (compare_mode)
16986 && code != GT && code != UNGE
16987 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16988 /* Constructs of the form (a OP b ? a : b) are safe. */
16989 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16990 || (! rtx_equal_p (op0, true_cond)
16991 && ! rtx_equal_p (op1, true_cond))))
16994 /* At this point we know we can use fsel. */
16996 /* Reduce the comparison to a comparison against zero. */
16997 if (! is_against_zero)
16999 temp = gen_reg_rtx (compare_mode);
17000 emit_insn (gen_rtx_SET (VOIDmode, temp,
17001 gen_rtx_MINUS (compare_mode, op0, op1)));
17003 op1 = CONST0_RTX (compare_mode);
17006 /* If we don't care about NaNs we can reduce some of the comparisons
17007 down to faster ones. */
17008 if (! HONOR_NANS (compare_mode))
17014 true_cond = false_cond;
17027 /* Now, reduce everything down to a GE. */
17034 temp = gen_reg_rtx (compare_mode);
17035 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17040 temp = gen_reg_rtx (compare_mode);
17041 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17046 temp = gen_reg_rtx (compare_mode);
17047 emit_insn (gen_rtx_SET (VOIDmode, temp,
17048 gen_rtx_NEG (compare_mode,
17049 gen_rtx_ABS (compare_mode, op0))));
17054 /* a UNGE 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 false_cond = true_cond;
17064 temp = gen_reg_rtx (compare_mode);
17065 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17070 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17071 temp = gen_reg_rtx (result_mode);
17072 emit_insn (gen_rtx_SET (VOIDmode, temp,
17073 gen_rtx_IF_THEN_ELSE (result_mode,
17074 gen_rtx_GE (VOIDmode,
17076 true_cond, false_cond)));
17077 true_cond = false_cond;
17080 temp = gen_reg_rtx (compare_mode);
17081 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17086 gcc_unreachable ();
17089 emit_insn (gen_rtx_SET (VOIDmode, dest,
17090 gen_rtx_IF_THEN_ELSE (result_mode,
17091 gen_rtx_GE (VOIDmode,
17093 true_cond, false_cond)));
17097 /* Same as above, but for ints (isel). */
17100 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17102 rtx condition_rtx, cr;
17103 enum machine_mode mode = GET_MODE (dest);
17104 enum rtx_code cond_code;
17105 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17108 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17111 /* We still have to do the compare, because isel doesn't do a
17112 compare, it just looks at the CRx bits set by a previous compare
17114 condition_rtx = rs6000_generate_compare (op, mode);
17115 cond_code = GET_CODE (condition_rtx);
17116 cr = XEXP (condition_rtx, 0);
17117 signedp = GET_MODE (cr) == CCmode;
17119 isel_func = (mode == SImode
17120 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17121 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17125 case LT: case GT: case LTU: case GTU: case EQ:
17126 /* isel handles these directly. */
17130 /* We need to swap the sense of the comparison. */
17133 true_cond = false_cond;
17135 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17140 false_cond = force_reg (mode, false_cond);
17141 if (true_cond != const0_rtx)
17142 true_cond = force_reg (mode, true_cond);
17144 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17150 output_isel (rtx *operands)
17152 enum rtx_code code;
17154 code = GET_CODE (operands[1]);
17156 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17158 gcc_assert (GET_CODE (operands[2]) == REG
17159 && GET_CODE (operands[3]) == REG);
17160 PUT_CODE (operands[1], reverse_condition (code));
17161 return "isel %0,%3,%2,%j1";
17164 return "isel %0,%2,%3,%j1";
17168 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17170 enum machine_mode mode = GET_MODE (op0);
17174 /* VSX/altivec have direct min/max insns. */
17175 if ((code == SMAX || code == SMIN)
17176 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17177 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17179 emit_insn (gen_rtx_SET (VOIDmode,
17181 gen_rtx_fmt_ee (code, mode, op0, op1)));
17185 if (code == SMAX || code == SMIN)
17190 if (code == SMAX || code == UMAX)
17191 target = emit_conditional_move (dest, c, op0, op1, mode,
17192 op0, op1, mode, 0);
17194 target = emit_conditional_move (dest, c, op0, op1, mode,
17195 op1, op0, mode, 0);
17196 gcc_assert (target);
17197 if (target != dest)
17198 emit_move_insn (dest, target);
17201 /* Emit instructions to perform a load-reserved/store-conditional operation.
17202 The operation performed is an atomic
17203 (set M (CODE:MODE M OP))
17204 If not NULL, BEFORE is atomically set to M before the operation, and
17205 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17206 If SYNC_P then a memory barrier is emitted before the operation.
17207 Either OP or M may be wrapped in a NOT operation. */
17210 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17211 rtx m, rtx op, rtx before_param, rtx after_param,
17214 enum machine_mode used_mode;
17215 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17218 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17219 rtx shift = NULL_RTX;
17222 emit_insn (gen_lwsync ());
17226 /* If this is smaller than SImode, we'll have to use SImode with
17228 if (mode == QImode || mode == HImode)
17232 if (MEM_ALIGN (used_m) >= 32)
17235 if (BYTES_BIG_ENDIAN)
17236 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17238 shift = GEN_INT (ishift);
17239 used_m = change_address (used_m, SImode, 0);
17243 rtx addrSI, aligned_addr;
17244 int shift_mask = mode == QImode ? 0x18 : 0x10;
17246 addrSI = gen_lowpart_common (SImode,
17247 force_reg (Pmode, XEXP (used_m, 0)));
17248 addrSI = force_reg (SImode, addrSI);
17249 shift = gen_reg_rtx (SImode);
17251 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17252 GEN_INT (shift_mask)));
17253 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17255 aligned_addr = expand_binop (Pmode, and_optab,
17257 GEN_INT (-4), NULL_RTX,
17258 1, OPTAB_LIB_WIDEN);
17259 used_m = change_address (used_m, SImode, aligned_addr);
17260 set_mem_align (used_m, 32);
17262 /* It's safe to keep the old alias set of USED_M, because
17263 the operation is atomic and only affects the original
17267 if (GET_CODE (op) == NOT)
17269 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17270 oldop = gen_rtx_NOT (SImode, oldop);
17273 oldop = lowpart_subreg (SImode, op, mode);
17279 newop = expand_binop (SImode, and_optab,
17280 oldop, GEN_INT (imask), NULL_RTX,
17281 1, OPTAB_LIB_WIDEN);
17282 emit_insn (gen_ashlsi3 (newop, newop, shift));
17285 case NOT: /* NAND */
17286 newop = expand_binop (SImode, ior_optab,
17287 oldop, GEN_INT (~imask), NULL_RTX,
17288 1, OPTAB_LIB_WIDEN);
17289 emit_insn (gen_rotlsi3 (newop, newop, shift));
17293 newop = expand_binop (SImode, ior_optab,
17294 oldop, GEN_INT (~imask), NULL_RTX,
17295 1, OPTAB_LIB_WIDEN);
17296 emit_insn (gen_rotlsi3 (newop, newop, shift));
17304 newop = expand_binop (SImode, and_optab,
17305 oldop, GEN_INT (imask), NULL_RTX,
17306 1, OPTAB_LIB_WIDEN);
17307 emit_insn (gen_ashlsi3 (newop, newop, shift));
17309 mask = gen_reg_rtx (SImode);
17310 emit_move_insn (mask, GEN_INT (imask));
17311 emit_insn (gen_ashlsi3 (mask, mask, shift));
17314 newop = gen_rtx_PLUS (SImode, m, newop);
17316 newop = gen_rtx_MINUS (SImode, m, newop);
17317 newop = gen_rtx_AND (SImode, newop, mask);
17318 newop = gen_rtx_IOR (SImode, newop,
17319 gen_rtx_AND (SImode,
17320 gen_rtx_NOT (SImode, mask),
17326 gcc_unreachable ();
17330 used_mode = SImode;
17331 before = gen_reg_rtx (used_mode);
17332 after = gen_reg_rtx (used_mode);
17337 before = before_param;
17338 after = after_param;
17340 if (before == NULL_RTX)
17341 before = gen_reg_rtx (used_mode);
17342 if (after == NULL_RTX)
17343 after = gen_reg_rtx (used_mode);
17346 if ((code == PLUS || code == MINUS)
17347 && used_mode != mode)
17348 the_op = op; /* Computed above. */
17349 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17350 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17351 else if (code == NOT)
17352 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17353 gen_rtx_NOT (used_mode, m),
17354 gen_rtx_NOT (used_mode, op));
17356 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17358 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17359 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17360 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17361 gen_rtx_UNSPEC (used_mode,
17362 gen_rtvec (1, the_op),
17364 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17366 if ((code == PLUS || code == MINUS) && used_mode != mode)
17367 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17368 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17370 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17371 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17373 /* Shift and mask the return values properly. */
17374 if (used_mode != mode && before_param)
17376 emit_insn (gen_lshrsi3 (before, before, shift));
17377 convert_move (before_param, before, 1);
17380 if (used_mode != mode && after_param)
17382 emit_insn (gen_lshrsi3 (after, after, shift));
17383 convert_move (after_param, after, 1);
17386 /* The previous sequence will end with a branch that's dependent on
17387 the conditional store, so placing an isync will ensure that no
17388 other instructions (especially, no load or store instructions)
17389 can start before the atomic operation completes. */
17391 emit_insn (gen_isync ());
17394 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17395 COND is true. Mark the jump as unlikely to be taken. */
17398 emit_unlikely_jump (rtx cond, rtx label)
17400 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17403 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17404 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17405 add_reg_note (x, REG_BR_PROB, very_unlikely);
17408 /* A subroutine of the atomic operation splitters. Emit a load-locked
17409 instruction in MODE. */
17412 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17414 rtx (*fn) (rtx, rtx) = NULL;
17415 if (mode == SImode)
17416 fn = gen_load_locked_si;
17417 else if (mode == DImode)
17418 fn = gen_load_locked_di;
17419 emit_insn (fn (reg, mem));
17422 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17423 instruction in MODE. */
17426 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17428 rtx (*fn) (rtx, rtx, rtx) = NULL;
17429 if (mode == SImode)
17430 fn = gen_store_conditional_si;
17431 else if (mode == DImode)
17432 fn = gen_store_conditional_di;
17434 /* Emit sync before stwcx. to address PPC405 Erratum. */
17435 if (PPC405_ERRATUM77)
17436 emit_insn (gen_memory_barrier ());
17438 emit_insn (fn (res, mem, val));
17441 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17442 to perform. MEM is the memory on which to operate. VAL is the second
17443 operand of the binary operator. BEFORE and AFTER are optional locations to
17444 return the value of MEM either before of after the operation. SCRATCH is
17445 a scratch register. */
17448 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17449 rtx before, rtx after, rtx scratch)
17451 enum machine_mode mode = GET_MODE (mem);
17452 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17454 emit_insn (gen_lwsync ());
17456 label = gen_label_rtx ();
17457 emit_label (label);
17458 label = gen_rtx_LABEL_REF (VOIDmode, label);
17460 if (before == NULL_RTX)
17462 emit_load_locked (mode, before, mem);
17465 x = gen_rtx_IOR (mode,
17466 gen_rtx_NOT (mode, before),
17467 gen_rtx_NOT (mode, val));
17468 else if (code == AND)
17469 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17471 x = gen_rtx_fmt_ee (code, mode, before, val);
17473 if (after != NULL_RTX)
17474 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17475 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17477 emit_store_conditional (mode, cond, mem, scratch);
17479 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17480 emit_unlikely_jump (x, label);
17482 emit_insn (gen_isync ());
17485 /* Expand an atomic compare and swap operation. MEM is the memory on which
17486 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17487 value to be stored. SCRATCH is a scratch GPR. */
17490 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17493 enum machine_mode mode = GET_MODE (mem);
17494 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17496 emit_insn (gen_lwsync ());
17498 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17499 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17500 emit_label (XEXP (label1, 0));
17502 emit_load_locked (mode, retval, mem);
17504 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17505 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17507 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17508 emit_unlikely_jump (x, label2);
17510 emit_move_insn (scratch, newval);
17511 emit_store_conditional (mode, cond, mem, scratch);
17513 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17514 emit_unlikely_jump (x, label1);
17516 emit_insn (gen_isync ());
17517 emit_label (XEXP (label2, 0));
17520 /* Expand an atomic test and set operation. MEM is the memory on which
17521 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17524 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17526 enum machine_mode mode = GET_MODE (mem);
17527 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17529 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17530 emit_label (XEXP (label, 0));
17532 emit_load_locked (mode, retval, mem);
17533 emit_move_insn (scratch, val);
17534 emit_store_conditional (mode, cond, mem, scratch);
17536 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17537 emit_unlikely_jump (x, label);
17539 emit_insn (gen_isync ());
17543 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17545 enum machine_mode mode = GET_MODE (mem);
17546 rtx addrSI, align, wdst, shift, mask;
17547 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17548 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17550 /* Shift amount for subword relative to aligned word. */
17551 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17552 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17553 shift = gen_reg_rtx (SImode);
17554 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17555 GEN_INT (shift_mask)));
17556 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17558 /* Shift and mask old value into position within word. */
17559 oldval = convert_modes (SImode, mode, oldval, 1);
17560 oldval = expand_binop (SImode, and_optab,
17561 oldval, GEN_INT (imask), NULL_RTX,
17562 1, OPTAB_LIB_WIDEN);
17563 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17565 /* Shift and mask new value into position within word. */
17566 newval = convert_modes (SImode, mode, newval, 1);
17567 newval = expand_binop (SImode, and_optab,
17568 newval, GEN_INT (imask), NULL_RTX,
17569 1, OPTAB_LIB_WIDEN);
17570 emit_insn (gen_ashlsi3 (newval, newval, shift));
17572 /* Mask for insertion. */
17573 mask = gen_reg_rtx (SImode);
17574 emit_move_insn (mask, GEN_INT (imask));
17575 emit_insn (gen_ashlsi3 (mask, mask, shift));
17577 /* Address of aligned word containing subword. */
17578 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17579 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17580 mem = change_address (mem, SImode, align);
17581 set_mem_align (mem, 32);
17582 MEM_VOLATILE_P (mem) = 1;
17584 wdst = gen_reg_rtx (SImode);
17585 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17586 oldval, newval, mem));
17588 /* Shift the result back. */
17589 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17591 emit_move_insn (dst, gen_lowpart (mode, wdst));
17595 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17596 rtx oldval, rtx newval, rtx mem,
17599 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17601 emit_insn (gen_lwsync ());
17602 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17603 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17604 emit_label (XEXP (label1, 0));
17606 emit_load_locked (SImode, scratch, mem);
17608 /* Mask subword within loaded value for comparison with oldval.
17609 Use UNSPEC_AND to avoid clobber.*/
17610 emit_insn (gen_rtx_SET (SImode, dest,
17611 gen_rtx_UNSPEC (SImode,
17612 gen_rtvec (2, scratch, mask),
17615 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17616 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17618 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17619 emit_unlikely_jump (x, label2);
17621 /* Clear subword within loaded value for insertion of new value. */
17622 emit_insn (gen_rtx_SET (SImode, scratch,
17623 gen_rtx_AND (SImode,
17624 gen_rtx_NOT (SImode, mask), scratch)));
17625 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17626 emit_store_conditional (SImode, cond, mem, scratch);
17628 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17629 emit_unlikely_jump (x, label1);
17631 emit_insn (gen_isync ());
17632 emit_label (XEXP (label2, 0));
17636 /* Emit instructions to move SRC to DST. Called by splitters for
17637 multi-register moves. It will emit at most one instruction for
17638 each register that is accessed; that is, it won't emit li/lis pairs
17639 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17643 rs6000_split_multireg_move (rtx dst, rtx src)
17645 /* The register number of the first register being moved. */
17647 /* The mode that is to be moved. */
17648 enum machine_mode mode;
17649 /* The mode that the move is being done in, and its size. */
17650 enum machine_mode reg_mode;
17652 /* The number of registers that will be moved. */
17655 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17656 mode = GET_MODE (dst);
17657 nregs = hard_regno_nregs[reg][mode];
17658 if (FP_REGNO_P (reg))
17659 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17660 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17661 else if (ALTIVEC_REGNO_P (reg))
17662 reg_mode = V16QImode;
17663 else if (TARGET_E500_DOUBLE && mode == TFmode)
17666 reg_mode = word_mode;
17667 reg_mode_size = GET_MODE_SIZE (reg_mode);
17669 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17671 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17673 /* Move register range backwards, if we might have destructive
17676 for (i = nregs - 1; i >= 0; i--)
17677 emit_insn (gen_rtx_SET (VOIDmode,
17678 simplify_gen_subreg (reg_mode, dst, mode,
17679 i * reg_mode_size),
17680 simplify_gen_subreg (reg_mode, src, mode,
17681 i * reg_mode_size)));
17687 bool used_update = false;
17688 rtx restore_basereg = NULL_RTX;
17690 if (MEM_P (src) && INT_REGNO_P (reg))
17694 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17695 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17698 breg = XEXP (XEXP (src, 0), 0);
17699 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17700 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17701 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17702 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17703 src = replace_equiv_address (src, breg);
17705 else if (! rs6000_offsettable_memref_p (src))
17707 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17709 rtx basereg = XEXP (XEXP (src, 0), 0);
17712 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17713 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17714 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17715 used_update = true;
17718 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17719 XEXP (XEXP (src, 0), 1)));
17720 src = replace_equiv_address (src, basereg);
17724 rtx basereg = gen_rtx_REG (Pmode, reg);
17725 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17726 src = replace_equiv_address (src, basereg);
17730 breg = XEXP (src, 0);
17731 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17732 breg = XEXP (breg, 0);
17734 /* If the base register we are using to address memory is
17735 also a destination reg, then change that register last. */
17737 && REGNO (breg) >= REGNO (dst)
17738 && REGNO (breg) < REGNO (dst) + nregs)
17739 j = REGNO (breg) - REGNO (dst);
17741 else if (MEM_P (dst) && INT_REGNO_P (reg))
17745 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17746 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17749 breg = XEXP (XEXP (dst, 0), 0);
17750 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17751 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17752 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17754 /* We have to update the breg before doing the store.
17755 Use store with update, if available. */
17759 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17760 emit_insn (TARGET_32BIT
17761 ? (TARGET_POWERPC64
17762 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17763 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17764 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17765 used_update = true;
17768 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17769 dst = replace_equiv_address (dst, breg);
17771 else if (!rs6000_offsettable_memref_p (dst)
17772 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17774 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17776 rtx basereg = XEXP (XEXP (dst, 0), 0);
17779 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17780 emit_insn (gen_rtx_SET (VOIDmode,
17781 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17782 used_update = true;
17785 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17786 XEXP (XEXP (dst, 0), 1)));
17787 dst = replace_equiv_address (dst, basereg);
17791 rtx basereg = XEXP (XEXP (dst, 0), 0);
17792 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17793 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17795 && REG_P (offsetreg)
17796 && REGNO (basereg) != REGNO (offsetreg));
17797 if (REGNO (basereg) == 0)
17799 rtx tmp = offsetreg;
17800 offsetreg = basereg;
17803 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17804 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17805 dst = replace_equiv_address (dst, basereg);
17808 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17809 gcc_assert (rs6000_offsettable_memref_p (dst));
17812 for (i = 0; i < nregs; i++)
17814 /* Calculate index to next subword. */
17819 /* If compiler already emitted move of first word by
17820 store with update, no need to do anything. */
17821 if (j == 0 && used_update)
17824 emit_insn (gen_rtx_SET (VOIDmode,
17825 simplify_gen_subreg (reg_mode, dst, mode,
17826 j * reg_mode_size),
17827 simplify_gen_subreg (reg_mode, src, mode,
17828 j * reg_mode_size)));
17830 if (restore_basereg != NULL_RTX)
17831 emit_insn (restore_basereg);
17836 /* This page contains routines that are used to determine what the
17837 function prologue and epilogue code will do and write them out. */
17839 /* Return the first fixed-point register that is required to be
17840 saved. 32 if none. */
17843 first_reg_to_save (void)
17847 /* Find lowest numbered live register. */
17848 for (first_reg = 13; first_reg <= 31; first_reg++)
17849 if (df_regs_ever_live_p (first_reg)
17850 && (! call_used_regs[first_reg]
17851 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17852 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17853 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17854 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17859 && crtl->uses_pic_offset_table
17860 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17861 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17867 /* Similar, for FP regs. */
17870 first_fp_reg_to_save (void)
17874 /* Find lowest numbered live register. */
17875 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17876 if (df_regs_ever_live_p (first_reg))
17882 /* Similar, for AltiVec regs. */
17885 first_altivec_reg_to_save (void)
17889 /* Stack frame remains as is unless we are in AltiVec ABI. */
17890 if (! TARGET_ALTIVEC_ABI)
17891 return LAST_ALTIVEC_REGNO + 1;
17893 /* On Darwin, the unwind routines are compiled without
17894 TARGET_ALTIVEC, and use save_world to save/restore the
17895 altivec registers when necessary. */
17896 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17897 && ! TARGET_ALTIVEC)
17898 return FIRST_ALTIVEC_REGNO + 20;
17900 /* Find lowest numbered live register. */
17901 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17902 if (df_regs_ever_live_p (i))
17908 /* Return a 32-bit mask of the AltiVec registers we need to set in
17909 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17910 the 32-bit word is 0. */
17912 static unsigned int
17913 compute_vrsave_mask (void)
17915 unsigned int i, mask = 0;
17917 /* On Darwin, the unwind routines are compiled without
17918 TARGET_ALTIVEC, and use save_world to save/restore the
17919 call-saved altivec registers when necessary. */
17920 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17921 && ! TARGET_ALTIVEC)
17924 /* First, find out if we use _any_ altivec registers. */
17925 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17926 if (df_regs_ever_live_p (i))
17927 mask |= ALTIVEC_REG_BIT (i);
17932 /* Next, remove the argument registers from the set. These must
17933 be in the VRSAVE mask set by the caller, so we don't need to add
17934 them in again. More importantly, the mask we compute here is
17935 used to generate CLOBBERs in the set_vrsave insn, and we do not
17936 wish the argument registers to die. */
17937 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17938 mask &= ~ALTIVEC_REG_BIT (i);
17940 /* Similarly, remove the return value from the set. */
17943 diddle_return_value (is_altivec_return_reg, &yes);
17945 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17951 /* For a very restricted set of circumstances, we can cut down the
17952 size of prologues/epilogues by calling our own save/restore-the-world
17956 compute_save_world_info (rs6000_stack_t *info_ptr)
17958 info_ptr->world_save_p = 1;
17959 info_ptr->world_save_p
17960 = (WORLD_SAVE_P (info_ptr)
17961 && DEFAULT_ABI == ABI_DARWIN
17962 && ! (cfun->calls_setjmp && flag_exceptions)
17963 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17964 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17965 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17966 && info_ptr->cr_save_p);
17968 /* This will not work in conjunction with sibcalls. Make sure there
17969 are none. (This check is expensive, but seldom executed.) */
17970 if (WORLD_SAVE_P (info_ptr))
17973 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17974 if ( GET_CODE (insn) == CALL_INSN
17975 && SIBLING_CALL_P (insn))
17977 info_ptr->world_save_p = 0;
17982 if (WORLD_SAVE_P (info_ptr))
17984 /* Even if we're not touching VRsave, make sure there's room on the
17985 stack for it, if it looks like we're calling SAVE_WORLD, which
17986 will attempt to save it. */
17987 info_ptr->vrsave_size = 4;
17989 /* If we are going to save the world, we need to save the link register too. */
17990 info_ptr->lr_save_p = 1;
17992 /* "Save" the VRsave register too if we're saving the world. */
17993 if (info_ptr->vrsave_mask == 0)
17994 info_ptr->vrsave_mask = compute_vrsave_mask ();
17996 /* Because the Darwin register save/restore routines only handle
17997 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17999 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18000 && (info_ptr->first_altivec_reg_save
18001 >= FIRST_SAVED_ALTIVEC_REGNO));
18008 is_altivec_return_reg (rtx reg, void *xyes)
18010 bool *yes = (bool *) xyes;
18011 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18016 /* Determine the strategy for savings/restoring registers. */
18019 SAVRES_MULTIPLE = 0x1,
18020 SAVE_INLINE_FPRS = 0x2,
18021 SAVE_INLINE_GPRS = 0x4,
18022 REST_INLINE_FPRS = 0x8,
18023 REST_INLINE_GPRS = 0x10,
18024 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18025 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18026 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18030 rs6000_savres_strategy (rs6000_stack_t *info,
18031 bool using_static_chain_p)
18035 if (TARGET_MULTIPLE
18036 && !TARGET_POWERPC64
18037 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18038 && info->first_gp_reg_save < 31
18039 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18040 strategy |= SAVRES_MULTIPLE;
18042 if (crtl->calls_eh_return
18043 || cfun->machine->ra_need_lr
18044 || info->total_size > 32767)
18045 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18046 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18048 if (info->first_fp_reg_save == 64
18049 || FP_SAVE_INLINE (info->first_fp_reg_save)
18050 /* The out-of-line FP routines use double-precision stores;
18051 we can't use those routines if we don't have such stores. */
18052 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18053 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18054 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18056 if (info->first_gp_reg_save == 32
18057 || GP_SAVE_INLINE (info->first_gp_reg_save)
18058 || !((strategy & SAVRES_MULTIPLE)
18059 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18060 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18062 /* Don't bother to try to save things out-of-line if r11 is occupied
18063 by the static chain. It would require too much fiddling and the
18064 static chain is rarely used anyway. */
18065 if (using_static_chain_p)
18066 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18068 /* If we are going to use store multiple, then don't even bother
18069 with the out-of-line routines, since the store-multiple
18070 instruction will always be smaller. */
18071 if ((strategy & SAVRES_MULTIPLE))
18072 strategy |= SAVE_INLINE_GPRS;
18074 /* The situation is more complicated with load multiple. We'd
18075 prefer to use the out-of-line routines for restores, since the
18076 "exit" out-of-line routines can handle the restore of LR and the
18077 frame teardown. However if doesn't make sense to use the
18078 out-of-line routine if that is the only reason we'd need to save
18079 LR, and we can't use the "exit" out-of-line gpr restore if we
18080 have saved some fprs; In those cases it is advantageous to use
18081 load multiple when available. */
18082 if ((strategy & SAVRES_MULTIPLE)
18083 && (!info->lr_save_p
18084 || info->first_fp_reg_save != 64))
18085 strategy |= REST_INLINE_GPRS;
18087 /* We can only use load multiple or the out-of-line routines to
18088 restore if we've used store multiple or out-of-line routines
18089 in the prologue, i.e. if we've saved all the registers from
18090 first_gp_reg_save. Otherwise, we risk loading garbage. */
18091 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18092 strategy |= REST_INLINE_GPRS;
18094 /* Saving CR interferes with the exit routines used on the SPE, so
18097 && info->spe_64bit_regs_used
18098 && info->cr_save_p)
18099 strategy |= REST_INLINE_GPRS;
18101 #ifdef POWERPC_LINUX
18104 if (!(strategy & SAVE_INLINE_FPRS))
18105 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18106 else if (!(strategy & SAVE_INLINE_GPRS)
18107 && info->first_fp_reg_save == 64)
18108 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18111 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18112 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18117 /* Calculate the stack information for the current function. This is
18118 complicated by having two separate calling sequences, the AIX calling
18119 sequence and the V.4 calling sequence.
18121 AIX (and Darwin/Mac OS X) stack frames look like:
18123 SP----> +---------------------------------------+
18124 | back chain to caller | 0 0
18125 +---------------------------------------+
18126 | saved CR | 4 8 (8-11)
18127 +---------------------------------------+
18129 +---------------------------------------+
18130 | reserved for compilers | 12 24
18131 +---------------------------------------+
18132 | reserved for binders | 16 32
18133 +---------------------------------------+
18134 | saved TOC pointer | 20 40
18135 +---------------------------------------+
18136 | Parameter save area (P) | 24 48
18137 +---------------------------------------+
18138 | Alloca space (A) | 24+P etc.
18139 +---------------------------------------+
18140 | Local variable space (L) | 24+P+A
18141 +---------------------------------------+
18142 | Float/int conversion temporary (X) | 24+P+A+L
18143 +---------------------------------------+
18144 | Save area for AltiVec registers (W) | 24+P+A+L+X
18145 +---------------------------------------+
18146 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18147 +---------------------------------------+
18148 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18149 +---------------------------------------+
18150 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18151 +---------------------------------------+
18152 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18153 +---------------------------------------+
18154 old SP->| back chain to caller's caller |
18155 +---------------------------------------+
18157 The required alignment for AIX configurations is two words (i.e., 8
18161 V.4 stack frames look like:
18163 SP----> +---------------------------------------+
18164 | back chain to caller | 0
18165 +---------------------------------------+
18166 | caller's saved LR | 4
18167 +---------------------------------------+
18168 | Parameter save area (P) | 8
18169 +---------------------------------------+
18170 | Alloca space (A) | 8+P
18171 +---------------------------------------+
18172 | Varargs save area (V) | 8+P+A
18173 +---------------------------------------+
18174 | Local variable space (L) | 8+P+A+V
18175 +---------------------------------------+
18176 | Float/int conversion temporary (X) | 8+P+A+V+L
18177 +---------------------------------------+
18178 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18179 +---------------------------------------+
18180 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18181 +---------------------------------------+
18182 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18183 +---------------------------------------+
18184 | SPE: area for 64-bit GP registers |
18185 +---------------------------------------+
18186 | SPE alignment padding |
18187 +---------------------------------------+
18188 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18189 +---------------------------------------+
18190 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18191 +---------------------------------------+
18192 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18193 +---------------------------------------+
18194 old SP->| back chain to caller's caller |
18195 +---------------------------------------+
18197 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18198 given. (But note below and in sysv4.h that we require only 8 and
18199 may round up the size of our stack frame anyways. The historical
18200 reason is early versions of powerpc-linux which didn't properly
18201 align the stack at program startup. A happy side-effect is that
18202 -mno-eabi libraries can be used with -meabi programs.)
18204 The EABI configuration defaults to the V.4 layout. However,
18205 the stack alignment requirements may differ. If -mno-eabi is not
18206 given, the required stack alignment is 8 bytes; if -mno-eabi is
18207 given, the required alignment is 16 bytes. (But see V.4 comment
18210 #ifndef ABI_STACK_BOUNDARY
18211 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18214 static rs6000_stack_t *
18215 rs6000_stack_info (void)
18217 rs6000_stack_t *info_ptr = &stack_info;
18218 int reg_size = TARGET_32BIT ? 4 : 8;
18222 HOST_WIDE_INT non_fixed_size;
18223 bool using_static_chain_p;
18225 if (reload_completed && info_ptr->reload_completed)
18228 memset (info_ptr, 0, sizeof (*info_ptr));
18229 info_ptr->reload_completed = reload_completed;
18233 /* Cache value so we don't rescan instruction chain over and over. */
18234 if (cfun->machine->insn_chain_scanned_p == 0)
18235 cfun->machine->insn_chain_scanned_p
18236 = spe_func_has_64bit_regs_p () + 1;
18237 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18240 /* Select which calling sequence. */
18241 info_ptr->abi = DEFAULT_ABI;
18243 /* Calculate which registers need to be saved & save area size. */
18244 info_ptr->first_gp_reg_save = first_reg_to_save ();
18245 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18246 even if it currently looks like we won't. Reload may need it to
18247 get at a constant; if so, it will have already created a constant
18248 pool entry for it. */
18249 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18250 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18251 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18252 && crtl->uses_const_pool
18253 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18254 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18256 first_gp = info_ptr->first_gp_reg_save;
18258 info_ptr->gp_size = reg_size * (32 - first_gp);
18260 /* For the SPE, we have an additional upper 32-bits on each GPR.
18261 Ideally we should save the entire 64-bits only when the upper
18262 half is used in SIMD instructions. Since we only record
18263 registers live (not the size they are used in), this proves
18264 difficult because we'd have to traverse the instruction chain at
18265 the right time, taking reload into account. This is a real pain,
18266 so we opt to save the GPRs in 64-bits always if but one register
18267 gets used in 64-bits. Otherwise, all the registers in the frame
18268 get saved in 32-bits.
18270 So... since when we save all GPRs (except the SP) in 64-bits, the
18271 traditional GP save area will be empty. */
18272 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18273 info_ptr->gp_size = 0;
18275 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18276 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18278 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18279 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18280 - info_ptr->first_altivec_reg_save);
18282 /* Does this function call anything? */
18283 info_ptr->calls_p = (! current_function_is_leaf
18284 || cfun->machine->ra_needs_full_frame);
18286 /* Determine if we need to save the condition code registers. */
18287 if (df_regs_ever_live_p (CR2_REGNO)
18288 || df_regs_ever_live_p (CR3_REGNO)
18289 || df_regs_ever_live_p (CR4_REGNO))
18291 info_ptr->cr_save_p = 1;
18292 if (DEFAULT_ABI == ABI_V4)
18293 info_ptr->cr_size = reg_size;
18296 /* If the current function calls __builtin_eh_return, then we need
18297 to allocate stack space for registers that will hold data for
18298 the exception handler. */
18299 if (crtl->calls_eh_return)
18302 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18305 /* SPE saves EH registers in 64-bits. */
18306 ehrd_size = i * (TARGET_SPE_ABI
18307 && info_ptr->spe_64bit_regs_used != 0
18308 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18313 /* Determine various sizes. */
18314 info_ptr->reg_size = reg_size;
18315 info_ptr->fixed_size = RS6000_SAVE_AREA;
18316 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18317 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18318 TARGET_ALTIVEC ? 16 : 8);
18319 if (FRAME_GROWS_DOWNWARD)
18320 info_ptr->vars_size
18321 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18322 + info_ptr->parm_size,
18323 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18324 - (info_ptr->fixed_size + info_ptr->vars_size
18325 + info_ptr->parm_size);
18327 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18328 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18330 info_ptr->spe_gp_size = 0;
18332 if (TARGET_ALTIVEC_ABI)
18333 info_ptr->vrsave_mask = compute_vrsave_mask ();
18335 info_ptr->vrsave_mask = 0;
18337 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18338 info_ptr->vrsave_size = 4;
18340 info_ptr->vrsave_size = 0;
18342 compute_save_world_info (info_ptr);
18344 /* Calculate the offsets. */
18345 switch (DEFAULT_ABI)
18349 gcc_unreachable ();
18353 info_ptr->fp_save_offset = - info_ptr->fp_size;
18354 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18356 if (TARGET_ALTIVEC_ABI)
18358 info_ptr->vrsave_save_offset
18359 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18361 /* Align stack so vector save area is on a quadword boundary.
18362 The padding goes above the vectors. */
18363 if (info_ptr->altivec_size != 0)
18364 info_ptr->altivec_padding_size
18365 = info_ptr->vrsave_save_offset & 0xF;
18367 info_ptr->altivec_padding_size = 0;
18369 info_ptr->altivec_save_offset
18370 = info_ptr->vrsave_save_offset
18371 - info_ptr->altivec_padding_size
18372 - info_ptr->altivec_size;
18373 gcc_assert (info_ptr->altivec_size == 0
18374 || info_ptr->altivec_save_offset % 16 == 0);
18376 /* Adjust for AltiVec case. */
18377 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18380 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18381 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18382 info_ptr->lr_save_offset = 2*reg_size;
18386 info_ptr->fp_save_offset = - info_ptr->fp_size;
18387 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18388 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18390 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18392 /* Align stack so SPE GPR save area is aligned on a
18393 double-word boundary. */
18394 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18395 info_ptr->spe_padding_size
18396 = 8 - (-info_ptr->cr_save_offset % 8);
18398 info_ptr->spe_padding_size = 0;
18400 info_ptr->spe_gp_save_offset
18401 = info_ptr->cr_save_offset
18402 - info_ptr->spe_padding_size
18403 - info_ptr->spe_gp_size;
18405 /* Adjust for SPE case. */
18406 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18408 else if (TARGET_ALTIVEC_ABI)
18410 info_ptr->vrsave_save_offset
18411 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18413 /* Align stack so vector save area is on a quadword boundary. */
18414 if (info_ptr->altivec_size != 0)
18415 info_ptr->altivec_padding_size
18416 = 16 - (-info_ptr->vrsave_save_offset % 16);
18418 info_ptr->altivec_padding_size = 0;
18420 info_ptr->altivec_save_offset
18421 = info_ptr->vrsave_save_offset
18422 - info_ptr->altivec_padding_size
18423 - info_ptr->altivec_size;
18425 /* Adjust for AltiVec case. */
18426 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18429 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18430 info_ptr->ehrd_offset -= ehrd_size;
18431 info_ptr->lr_save_offset = reg_size;
18435 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18436 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18437 + info_ptr->gp_size
18438 + info_ptr->altivec_size
18439 + info_ptr->altivec_padding_size
18440 + info_ptr->spe_gp_size
18441 + info_ptr->spe_padding_size
18443 + info_ptr->cr_size
18444 + info_ptr->vrsave_size,
18447 non_fixed_size = (info_ptr->vars_size
18448 + info_ptr->parm_size
18449 + info_ptr->save_size);
18451 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18452 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18454 /* Determine if we need to save the link register. */
18455 if (info_ptr->calls_p
18456 || (DEFAULT_ABI == ABI_AIX
18458 && !TARGET_PROFILE_KERNEL)
18459 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18460 #ifdef TARGET_RELOCATABLE
18461 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18463 || rs6000_ra_ever_killed ())
18464 info_ptr->lr_save_p = 1;
18466 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18467 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18468 && call_used_regs[STATIC_CHAIN_REGNUM]);
18469 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18470 using_static_chain_p);
18472 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18473 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18474 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18475 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18476 info_ptr->lr_save_p = 1;
18478 if (info_ptr->lr_save_p)
18479 df_set_regs_ever_live (LR_REGNO, true);
18481 /* Determine if we need to allocate any stack frame:
18483 For AIX we need to push the stack if a frame pointer is needed
18484 (because the stack might be dynamically adjusted), if we are
18485 debugging, if we make calls, or if the sum of fp_save, gp_save,
18486 and local variables are more than the space needed to save all
18487 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18488 + 18*8 = 288 (GPR13 reserved).
18490 For V.4 we don't have the stack cushion that AIX uses, but assume
18491 that the debugger can handle stackless frames. */
18493 if (info_ptr->calls_p)
18494 info_ptr->push_p = 1;
18496 else if (DEFAULT_ABI == ABI_V4)
18497 info_ptr->push_p = non_fixed_size != 0;
18499 else if (frame_pointer_needed)
18500 info_ptr->push_p = 1;
18502 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18503 info_ptr->push_p = 1;
18506 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18508 /* Zero offsets if we're not saving those registers. */
18509 if (info_ptr->fp_size == 0)
18510 info_ptr->fp_save_offset = 0;
18512 if (info_ptr->gp_size == 0)
18513 info_ptr->gp_save_offset = 0;
18515 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18516 info_ptr->altivec_save_offset = 0;
18518 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18519 info_ptr->vrsave_save_offset = 0;
18521 if (! TARGET_SPE_ABI
18522 || info_ptr->spe_64bit_regs_used == 0
18523 || info_ptr->spe_gp_size == 0)
18524 info_ptr->spe_gp_save_offset = 0;
18526 if (! info_ptr->lr_save_p)
18527 info_ptr->lr_save_offset = 0;
18529 if (! info_ptr->cr_save_p)
18530 info_ptr->cr_save_offset = 0;
18535 /* Return true if the current function uses any GPRs in 64-bit SIMD
18539 spe_func_has_64bit_regs_p (void)
18543 /* Functions that save and restore all the call-saved registers will
18544 need to save/restore the registers in 64-bits. */
18545 if (crtl->calls_eh_return
18546 || cfun->calls_setjmp
18547 || crtl->has_nonlocal_goto)
18550 insns = get_insns ();
18552 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18558 /* FIXME: This should be implemented with attributes...
18560 (set_attr "spe64" "true")....then,
18561 if (get_spe64(insn)) return true;
18563 It's the only reliable way to do the stuff below. */
18565 i = PATTERN (insn);
18566 if (GET_CODE (i) == SET)
18568 enum machine_mode mode = GET_MODE (SET_SRC (i));
18570 if (SPE_VECTOR_MODE (mode))
18572 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18582 debug_stack_info (rs6000_stack_t *info)
18584 const char *abi_string;
18587 info = rs6000_stack_info ();
18589 fprintf (stderr, "\nStack information for function %s:\n",
18590 ((current_function_decl && DECL_NAME (current_function_decl))
18591 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18596 default: abi_string = "Unknown"; break;
18597 case ABI_NONE: abi_string = "NONE"; break;
18598 case ABI_AIX: abi_string = "AIX"; break;
18599 case ABI_DARWIN: abi_string = "Darwin"; break;
18600 case ABI_V4: abi_string = "V.4"; break;
18603 fprintf (stderr, "\tABI = %5s\n", abi_string);
18605 if (TARGET_ALTIVEC_ABI)
18606 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18608 if (TARGET_SPE_ABI)
18609 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18611 if (info->first_gp_reg_save != 32)
18612 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18614 if (info->first_fp_reg_save != 64)
18615 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18617 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18618 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18619 info->first_altivec_reg_save);
18621 if (info->lr_save_p)
18622 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18624 if (info->cr_save_p)
18625 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18627 if (info->vrsave_mask)
18628 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18631 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18634 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18636 if (info->gp_save_offset)
18637 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18639 if (info->fp_save_offset)
18640 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18642 if (info->altivec_save_offset)
18643 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18644 info->altivec_save_offset);
18646 if (info->spe_gp_save_offset)
18647 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18648 info->spe_gp_save_offset);
18650 if (info->vrsave_save_offset)
18651 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18652 info->vrsave_save_offset);
18654 if (info->lr_save_offset)
18655 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18657 if (info->cr_save_offset)
18658 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18660 if (info->varargs_save_offset)
18661 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18663 if (info->total_size)
18664 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18667 if (info->vars_size)
18668 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18671 if (info->parm_size)
18672 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18674 if (info->fixed_size)
18675 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18678 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18680 if (info->spe_gp_size)
18681 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18684 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18686 if (info->altivec_size)
18687 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18689 if (info->vrsave_size)
18690 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18692 if (info->altivec_padding_size)
18693 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18694 info->altivec_padding_size);
18696 if (info->spe_padding_size)
18697 fprintf (stderr, "\tspe_padding_size = %5d\n",
18698 info->spe_padding_size);
18701 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18703 if (info->save_size)
18704 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18706 if (info->reg_size != 4)
18707 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18709 fprintf (stderr, "\n");
18713 rs6000_return_addr (int count, rtx frame)
18715 /* Currently we don't optimize very well between prolog and body
18716 code and for PIC code the code can be actually quite bad, so
18717 don't try to be too clever here. */
18718 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18720 cfun->machine->ra_needs_full_frame = 1;
18727 plus_constant (copy_to_reg
18728 (gen_rtx_MEM (Pmode,
18729 memory_address (Pmode, frame))),
18730 RETURN_ADDRESS_OFFSET)));
18733 cfun->machine->ra_need_lr = 1;
18734 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18737 /* Say whether a function is a candidate for sibcall handling or not. */
18740 rs6000_function_ok_for_sibcall (tree decl, tree exp)
18745 fntype = TREE_TYPE (decl);
18747 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
18749 /* We can't do it if the called function has more vector parameters
18750 than the current function; there's nowhere to put the VRsave code. */
18751 if (TARGET_ALTIVEC_ABI
18752 && TARGET_ALTIVEC_VRSAVE
18753 && !(decl && decl == current_function_decl))
18755 function_args_iterator args_iter;
18759 /* Functions with vector parameters are required to have a
18760 prototype, so the argument type info must be available
18762 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
18763 if (TREE_CODE (type) == VECTOR_TYPE
18764 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18767 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
18768 if (TREE_CODE (type) == VECTOR_TYPE
18769 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18776 /* Under the AIX ABI we can't allow calls to non-local functions,
18777 because the callee may have a different TOC pointer to the
18778 caller and there's no way to ensure we restore the TOC when we
18779 return. With the secure-plt SYSV ABI we can't make non-local
18780 calls when -fpic/PIC because the plt call stubs use r30. */
18781 if (DEFAULT_ABI == ABI_DARWIN
18782 || (DEFAULT_ABI == ABI_AIX
18784 && !DECL_EXTERNAL (decl)
18785 && (*targetm.binds_local_p) (decl))
18786 || (DEFAULT_ABI == ABI_V4
18787 && (!TARGET_SECURE_PLT
18790 && (*targetm.binds_local_p) (decl)))))
18792 tree attr_list = TYPE_ATTRIBUTES (fntype);
18794 if (!lookup_attribute ("longcall", attr_list)
18795 || lookup_attribute ("shortcall", attr_list))
18802 /* NULL if INSN insn is valid within a low-overhead loop.
18803 Otherwise return why doloop cannot be applied.
18804 PowerPC uses the COUNT register for branch on table instructions. */
18806 static const char *
18807 rs6000_invalid_within_doloop (const_rtx insn)
18810 return "Function call in the loop.";
18813 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18814 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18815 return "Computed branch in the loop.";
18821 rs6000_ra_ever_killed (void)
18827 if (cfun->is_thunk)
18830 if (cfun->machine->lr_save_state)
18831 return cfun->machine->lr_save_state - 1;
18833 /* regs_ever_live has LR marked as used if any sibcalls are present,
18834 but this should not force saving and restoring in the
18835 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18836 clobbers LR, so that is inappropriate. */
18838 /* Also, the prologue can generate a store into LR that
18839 doesn't really count, like this:
18842 bcl to set PIC register
18846 When we're called from the epilogue, we need to avoid counting
18847 this as a store. */
18849 push_topmost_sequence ();
18850 top = get_insns ();
18851 pop_topmost_sequence ();
18852 reg = gen_rtx_REG (Pmode, LR_REGNO);
18854 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18860 if (!SIBLING_CALL_P (insn))
18863 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18865 else if (set_of (reg, insn) != NULL_RTX
18866 && !prologue_epilogue_contains (insn))
18873 /* Emit instructions needed to load the TOC register.
18874 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18875 a constant pool; or for SVR4 -fpic. */
18878 rs6000_emit_load_toc_table (int fromprolog)
18881 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18883 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18886 rtx lab, tmp1, tmp2, got;
18888 lab = gen_label_rtx ();
18889 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18890 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18892 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18894 got = rs6000_got_sym ();
18895 tmp1 = tmp2 = dest;
18898 tmp1 = gen_reg_rtx (Pmode);
18899 tmp2 = gen_reg_rtx (Pmode);
18901 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18902 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18903 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18904 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18906 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18908 emit_insn (gen_load_toc_v4_pic_si ());
18909 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18911 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18914 rtx temp0 = (fromprolog
18915 ? gen_rtx_REG (Pmode, 0)
18916 : gen_reg_rtx (Pmode));
18922 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18923 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18925 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18926 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18928 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18929 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18930 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18936 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18937 lab = gen_label_rtx ();
18938 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18939 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18940 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18942 emit_insn (gen_addsi3 (dest, temp0, dest));
18944 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18946 /* This is for AIX code running in non-PIC ELF32. */
18949 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18950 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18952 emit_insn (gen_elf_high (dest, realsym));
18953 emit_insn (gen_elf_low (dest, dest, realsym));
18957 gcc_assert (DEFAULT_ABI == ABI_AIX);
18960 emit_insn (gen_load_toc_aix_si (dest));
18962 emit_insn (gen_load_toc_aix_di (dest));
18966 /* Emit instructions to restore the link register after determining where
18967 its value has been stored. */
18970 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18972 rs6000_stack_t *info = rs6000_stack_info ();
18975 operands[0] = source;
18976 operands[1] = scratch;
18978 if (info->lr_save_p)
18980 rtx frame_rtx = stack_pointer_rtx;
18981 HOST_WIDE_INT sp_offset = 0;
18984 if (frame_pointer_needed
18985 || cfun->calls_alloca
18986 || info->total_size > 32767)
18988 tmp = gen_frame_mem (Pmode, frame_rtx);
18989 emit_move_insn (operands[1], tmp);
18990 frame_rtx = operands[1];
18992 else if (info->push_p)
18993 sp_offset = info->total_size;
18995 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18996 tmp = gen_frame_mem (Pmode, tmp);
18997 emit_move_insn (tmp, operands[0]);
19000 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19002 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19003 state of lr_save_p so any change from here on would be a bug. In
19004 particular, stop rs6000_ra_ever_killed from considering the SET
19005 of lr we may have added just above. */
19006 cfun->machine->lr_save_state = info->lr_save_p + 1;
19009 static GTY(()) alias_set_type set = -1;
19012 get_TOC_alias_set (void)
19015 set = new_alias_set ();
19019 /* This returns nonzero if the current function uses the TOC. This is
19020 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19021 is generated by the ABI_V4 load_toc_* patterns. */
19028 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19031 rtx pat = PATTERN (insn);
19034 if (GET_CODE (pat) == PARALLEL)
19035 for (i = 0; i < XVECLEN (pat, 0); i++)
19037 rtx sub = XVECEXP (pat, 0, i);
19038 if (GET_CODE (sub) == USE)
19040 sub = XEXP (sub, 0);
19041 if (GET_CODE (sub) == UNSPEC
19042 && XINT (sub, 1) == UNSPEC_TOC)
19052 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19054 rtx tocrel, tocreg;
19056 if (TARGET_DEBUG_ADDR)
19058 if (GET_CODE (symbol) == SYMBOL_REF)
19059 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19063 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19064 GET_RTX_NAME (GET_CODE (symbol)));
19065 debug_rtx (symbol);
19069 if (!can_create_pseudo_p ())
19070 df_set_regs_ever_live (TOC_REGISTER, true);
19072 tocrel = gen_rtx_CONST (Pmode,
19073 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19075 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19076 if (TARGET_CMODEL != CMODEL_SMALL)
19078 rtx hi = gen_rtx_CONST (Pmode,
19079 gen_rtx_PLUS (Pmode, tocreg,
19080 gen_rtx_HIGH (Pmode, tocrel)));
19081 if (largetoc_reg != NULL)
19083 emit_move_insn (largetoc_reg, hi);
19086 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19089 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19092 /* Issue assembly directives that create a reference to the given DWARF
19093 FRAME_TABLE_LABEL from the current function section. */
19095 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19097 fprintf (asm_out_file, "\t.ref %s\n",
19098 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19101 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19102 and the change to the stack pointer. */
19105 rs6000_emit_stack_tie (void)
19107 rtx mem = gen_frame_mem (BLKmode,
19108 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19110 emit_insn (gen_stack_tie (mem));
19113 /* Emit the correct code for allocating stack space, as insns.
19114 If COPY_REG, make sure a copy of the old frame is left there.
19115 The generated code may use hard register 0 as a temporary. */
19118 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19121 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19122 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19123 rtx todec = gen_int_mode (-size, Pmode);
19126 if (INTVAL (todec) != -size)
19128 warning (0, "stack frame too large");
19129 emit_insn (gen_trap ());
19133 if (crtl->limit_stack)
19135 if (REG_P (stack_limit_rtx)
19136 && REGNO (stack_limit_rtx) > 1
19137 && REGNO (stack_limit_rtx) <= 31)
19139 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19140 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19143 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19145 && DEFAULT_ABI == ABI_V4)
19147 rtx toload = gen_rtx_CONST (VOIDmode,
19148 gen_rtx_PLUS (Pmode,
19152 emit_insn (gen_elf_high (tmp_reg, toload));
19153 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19154 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19158 warning (0, "stack limit expression is not supported");
19162 emit_move_insn (copy_reg, stack_reg);
19166 /* Need a note here so that try_split doesn't get confused. */
19167 if (get_last_insn () == NULL_RTX)
19168 emit_note (NOTE_INSN_DELETED);
19169 insn = emit_move_insn (tmp_reg, todec);
19170 try_split (PATTERN (insn), insn, 0);
19174 insn = emit_insn (TARGET_32BIT
19175 ? gen_movsi_update_stack (stack_reg, stack_reg,
19177 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19178 todec, stack_reg));
19179 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19180 it now and set the alias set/attributes. The above gen_*_update
19181 calls will generate a PARALLEL with the MEM set being the first
19183 par = PATTERN (insn);
19184 gcc_assert (GET_CODE (par) == PARALLEL);
19185 set = XVECEXP (par, 0, 0);
19186 gcc_assert (GET_CODE (set) == SET);
19187 mem = SET_DEST (set);
19188 gcc_assert (MEM_P (mem));
19189 MEM_NOTRAP_P (mem) = 1;
19190 set_mem_alias_set (mem, get_frame_alias_set ());
19192 RTX_FRAME_RELATED_P (insn) = 1;
19193 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19194 gen_rtx_SET (VOIDmode, stack_reg,
19195 gen_rtx_PLUS (Pmode, stack_reg,
19196 GEN_INT (-size))));
19199 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19201 #if PROBE_INTERVAL > 32768
19202 #error Cannot use indexed addressing mode for stack probing
19205 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19206 inclusive. These are offsets from the current stack pointer. */
19209 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19211 /* See if we have a constant small number of probes to generate. If so,
19212 that's the easy case. */
19213 if (first + size <= 32768)
19217 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19218 it exceeds SIZE. If only one probe is needed, this will not
19219 generate any code. Then probe at FIRST + SIZE. */
19220 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19221 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19223 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19226 /* Otherwise, do the same as above, but in a loop. Note that we must be
19227 extra careful with variables wrapping around because we might be at
19228 the very top (or the very bottom) of the address space and we have
19229 to be able to handle this case properly; in particular, we use an
19230 equality test for the loop condition. */
19233 HOST_WIDE_INT rounded_size;
19234 rtx r12 = gen_rtx_REG (Pmode, 12);
19235 rtx r0 = gen_rtx_REG (Pmode, 0);
19237 /* Sanity check for the addressing mode we're going to use. */
19238 gcc_assert (first <= 32768);
19240 /* Step 1: round SIZE to the previous multiple of the interval. */
19242 rounded_size = size & -PROBE_INTERVAL;
19245 /* Step 2: compute initial and final value of the loop counter. */
19247 /* TEST_ADDR = SP + FIRST. */
19248 emit_insn (gen_rtx_SET (VOIDmode, r12,
19249 plus_constant (stack_pointer_rtx, -first)));
19251 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19252 if (rounded_size > 32768)
19254 emit_move_insn (r0, GEN_INT (-rounded_size));
19255 emit_insn (gen_rtx_SET (VOIDmode, r0,
19256 gen_rtx_PLUS (Pmode, r12, r0)));
19259 emit_insn (gen_rtx_SET (VOIDmode, r0,
19260 plus_constant (r12, -rounded_size)));
19263 /* Step 3: the loop
19265 while (TEST_ADDR != LAST_ADDR)
19267 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19271 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19272 until it is equal to ROUNDED_SIZE. */
19275 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19277 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19280 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19281 that SIZE is equal to ROUNDED_SIZE. */
19283 if (size != rounded_size)
19284 emit_stack_probe (plus_constant (r12, rounded_size - size));
19288 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19289 absolute addresses. */
19292 output_probe_stack_range (rtx reg1, rtx reg2)
19294 static int labelno = 0;
19295 char loop_lab[32], end_lab[32];
19298 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19299 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19301 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19303 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19307 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19309 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19311 fputs ("\tbeq 0,", asm_out_file);
19312 assemble_name_raw (asm_out_file, end_lab);
19313 fputc ('\n', asm_out_file);
19315 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19316 xops[1] = GEN_INT (-PROBE_INTERVAL);
19317 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19319 /* Probe at TEST_ADDR and branch. */
19320 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19321 fprintf (asm_out_file, "\tb ");
19322 assemble_name_raw (asm_out_file, loop_lab);
19323 fputc ('\n', asm_out_file);
19325 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19330 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19331 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19332 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19333 deduce these equivalences by itself so it wasn't necessary to hold
19334 its hand so much. */
19337 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19338 rtx reg2, rtx rreg)
19342 /* copy_rtx will not make unique copies of registers, so we need to
19343 ensure we don't have unwanted sharing here. */
19345 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19348 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19350 real = copy_rtx (PATTERN (insn));
19352 if (reg2 != NULL_RTX)
19353 real = replace_rtx (real, reg2, rreg);
19355 real = replace_rtx (real, reg,
19356 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19357 STACK_POINTER_REGNUM),
19360 /* We expect that 'real' is either a SET or a PARALLEL containing
19361 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19362 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19364 if (GET_CODE (real) == SET)
19368 temp = simplify_rtx (SET_SRC (set));
19370 SET_SRC (set) = temp;
19371 temp = simplify_rtx (SET_DEST (set));
19373 SET_DEST (set) = temp;
19374 if (GET_CODE (SET_DEST (set)) == MEM)
19376 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19378 XEXP (SET_DEST (set), 0) = temp;
19385 gcc_assert (GET_CODE (real) == PARALLEL);
19386 for (i = 0; i < XVECLEN (real, 0); i++)
19387 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19389 rtx set = XVECEXP (real, 0, i);
19391 temp = simplify_rtx (SET_SRC (set));
19393 SET_SRC (set) = temp;
19394 temp = simplify_rtx (SET_DEST (set));
19396 SET_DEST (set) = temp;
19397 if (GET_CODE (SET_DEST (set)) == MEM)
19399 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19401 XEXP (SET_DEST (set), 0) = temp;
19403 RTX_FRAME_RELATED_P (set) = 1;
19407 RTX_FRAME_RELATED_P (insn) = 1;
19408 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19411 /* Returns an insn that has a vrsave set operation with the
19412 appropriate CLOBBERs. */
19415 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19418 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19419 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19422 = gen_rtx_SET (VOIDmode,
19424 gen_rtx_UNSPEC_VOLATILE (SImode,
19425 gen_rtvec (2, reg, vrsave),
19426 UNSPECV_SET_VRSAVE));
19430 /* We need to clobber the registers in the mask so the scheduler
19431 does not move sets to VRSAVE before sets of AltiVec registers.
19433 However, if the function receives nonlocal gotos, reload will set
19434 all call saved registers live. We will end up with:
19436 (set (reg 999) (mem))
19437 (parallel [ (set (reg vrsave) (unspec blah))
19438 (clobber (reg 999))])
19440 The clobber will cause the store into reg 999 to be dead, and
19441 flow will attempt to delete an epilogue insn. In this case, we
19442 need an unspec use/set of the register. */
19444 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19445 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19447 if (!epiloguep || call_used_regs [i])
19448 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19449 gen_rtx_REG (V4SImode, i));
19452 rtx reg = gen_rtx_REG (V4SImode, i);
19455 = gen_rtx_SET (VOIDmode,
19457 gen_rtx_UNSPEC (V4SImode,
19458 gen_rtvec (1, reg), 27));
19462 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19464 for (i = 0; i < nclobs; ++i)
19465 XVECEXP (insn, 0, i) = clobs[i];
19470 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19471 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19474 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19475 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19477 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19478 rtx replacea, replaceb;
19480 int_rtx = GEN_INT (offset);
19482 /* Some cases that need register indexed addressing. */
19483 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19484 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19485 || (TARGET_E500_DOUBLE && mode == DFmode)
19487 && SPE_VECTOR_MODE (mode)
19488 && !SPE_CONST_OFFSET_OK (offset)))
19490 /* Whomever calls us must make sure r11 is available in the
19491 flow path of instructions in the prologue. */
19492 offset_rtx = gen_rtx_REG (Pmode, 11);
19493 emit_move_insn (offset_rtx, int_rtx);
19495 replacea = offset_rtx;
19496 replaceb = int_rtx;
19500 offset_rtx = int_rtx;
19501 replacea = NULL_RTX;
19502 replaceb = NULL_RTX;
19505 reg = gen_rtx_REG (mode, regno);
19506 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19507 mem = gen_frame_mem (mode, addr);
19509 insn = emit_move_insn (mem, reg);
19511 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19514 /* Emit an offset memory reference suitable for a frame store, while
19515 converting to a valid addressing mode. */
19518 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19520 rtx int_rtx, offset_rtx;
19522 int_rtx = GEN_INT (offset);
19524 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19525 || (TARGET_E500_DOUBLE && mode == DFmode))
19527 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19528 emit_move_insn (offset_rtx, int_rtx);
19531 offset_rtx = int_rtx;
19533 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19536 /* Look for user-defined global regs. We should not save and restore these,
19537 and cannot use stmw/lmw if there are any in its range. */
19540 no_global_regs_above (int first, bool gpr)
19543 int last = gpr ? 32 : 64;
19544 for (i = first; i < last; i++)
19545 if (global_regs[i])
19550 #ifndef TARGET_FIX_AND_CONTINUE
19551 #define TARGET_FIX_AND_CONTINUE 0
19554 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19555 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19556 #define LAST_SAVRES_REGISTER 31
19557 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19559 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19561 /* Temporary holding space for an out-of-line register save/restore
19563 static char savres_routine_name[30];
19565 /* Return the name for an out-of-line register save/restore routine.
19566 We are saving/restoring GPRs if GPR is true. */
19569 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19570 bool savep, bool gpr, bool lr)
19572 const char *prefix = "";
19573 const char *suffix = "";
19575 /* Different targets are supposed to define
19576 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19577 routine name could be defined with:
19579 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19581 This is a nice idea in practice, but in reality, things are
19582 complicated in several ways:
19584 - ELF targets have save/restore routines for GPRs.
19586 - SPE targets use different prefixes for 32/64-bit registers, and
19587 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19589 - PPC64 ELF targets have routines for save/restore of GPRs that
19590 differ in what they do with the link register, so having a set
19591 prefix doesn't work. (We only use one of the save routines at
19592 the moment, though.)
19594 - PPC32 elf targets have "exit" versions of the restore routines
19595 that restore the link register and can save some extra space.
19596 These require an extra suffix. (There are also "tail" versions
19597 of the restore routines and "GOT" versions of the save routines,
19598 but we don't generate those at present. Same problems apply,
19601 We deal with all this by synthesizing our own prefix/suffix and
19602 using that for the simple sprintf call shown above. */
19605 /* No floating point saves on the SPE. */
19609 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19611 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19616 else if (DEFAULT_ABI == ABI_V4)
19622 prefix = savep ? "_savegpr_" : "_restgpr_";
19624 prefix = savep ? "_savefpr_" : "_restfpr_";
19629 else if (DEFAULT_ABI == ABI_AIX)
19631 #ifndef POWERPC_LINUX
19632 /* No out-of-line save/restore routines for GPRs on AIX. */
19633 gcc_assert (!TARGET_AIX || !gpr);
19639 ? (lr ? "_savegpr0_" : "_savegpr1_")
19640 : (lr ? "_restgpr0_" : "_restgpr1_"));
19641 #ifdef POWERPC_LINUX
19643 prefix = (savep ? "_savefpr_" : "_restfpr_");
19647 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19648 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19651 else if (DEFAULT_ABI == ABI_DARWIN)
19652 sorry ("out-of-line save/restore routines not supported on Darwin");
19654 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19656 return savres_routine_name;
19659 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19660 We are saving/restoring GPRs if GPR is true. */
19663 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19666 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19668 int select = ((savep ? 1 : 0) << 2
19670 /* On the SPE, we never have any FPRs, but we do have
19671 32/64-bit versions of the routines. */
19672 ? (info->spe_64bit_regs_used ? 1 : 0)
19673 : (gpr ? 1 : 0)) << 1)
19676 /* Don't generate bogus routine names. */
19677 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19678 && regno <= LAST_SAVRES_REGISTER);
19680 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19686 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19688 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19689 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19690 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19696 /* Emit a sequence of insns, including a stack tie if needed, for
19697 resetting the stack pointer. If SAVRES is true, then don't reset the
19698 stack pointer, but move the base of the frame into r11 for use by
19699 out-of-line register restore routines. */
19702 rs6000_emit_stack_reset (rs6000_stack_t *info,
19703 rtx sp_reg_rtx, rtx frame_reg_rtx,
19704 int sp_offset, bool savres)
19706 /* This blockage is needed so that sched doesn't decide to move
19707 the sp change before the register restores. */
19708 if (frame_reg_rtx != sp_reg_rtx
19710 && info->spe_64bit_regs_used != 0
19711 && info->first_gp_reg_save != 32))
19712 rs6000_emit_stack_tie ();
19714 if (frame_reg_rtx != sp_reg_rtx)
19716 if (sp_offset != 0)
19718 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19719 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19720 GEN_INT (sp_offset)));
19723 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19725 else if (sp_offset != 0)
19727 /* If we are restoring registers out-of-line, we will be using the
19728 "exit" variants of the restore routines, which will reset the
19729 stack for us. But we do need to point r11 into the right place
19730 for those routines. */
19731 rtx dest_reg = (savres
19732 ? gen_rtx_REG (Pmode, 11)
19735 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19736 GEN_INT (sp_offset)));
19743 /* Construct a parallel rtx describing the effect of a call to an
19744 out-of-line register save/restore routine. */
19747 rs6000_make_savres_rtx (rs6000_stack_t *info,
19748 rtx frame_reg_rtx, int save_area_offset,
19749 enum machine_mode reg_mode,
19750 bool savep, bool gpr, bool lr)
19753 int offset, start_reg, end_reg, n_regs;
19754 int reg_size = GET_MODE_SIZE (reg_mode);
19760 ? info->first_gp_reg_save
19761 : info->first_fp_reg_save);
19762 end_reg = gpr ? 32 : 64;
19763 n_regs = end_reg - start_reg;
19764 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19767 RTVEC_ELT (p, offset++) = ret_rtx;
19769 RTVEC_ELT (p, offset++)
19770 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19772 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19773 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19774 RTVEC_ELT (p, offset++)
19775 = gen_rtx_USE (VOIDmode,
19776 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19780 for (i = 0; i < end_reg - start_reg; i++)
19782 rtx addr, reg, mem;
19783 reg = gen_rtx_REG (reg_mode, start_reg + i);
19784 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19785 GEN_INT (save_area_offset + reg_size*i));
19786 mem = gen_frame_mem (reg_mode, addr);
19788 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19790 savep ? reg : mem);
19795 rtx addr, reg, mem;
19796 reg = gen_rtx_REG (Pmode, 0);
19797 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19798 GEN_INT (info->lr_save_offset));
19799 mem = gen_frame_mem (Pmode, addr);
19800 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19803 return gen_rtx_PARALLEL (VOIDmode, p);
19806 /* Determine whether the gp REG is really used. */
19809 rs6000_reg_live_or_pic_offset_p (int reg)
19811 /* If the function calls eh_return, claim used all the registers that would
19812 be checked for liveness otherwise. This is required for the PIC offset
19813 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19814 register allocation purposes in this case. */
19816 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19817 && (!call_used_regs[reg]
19818 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19819 && !TARGET_SINGLE_PIC_BASE
19820 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19821 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19822 && !TARGET_SINGLE_PIC_BASE
19823 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19824 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19827 /* Emit function prologue as insns. */
19830 rs6000_emit_prologue (void)
19832 rs6000_stack_t *info = rs6000_stack_info ();
19833 enum machine_mode reg_mode = Pmode;
19834 int reg_size = TARGET_32BIT ? 4 : 8;
19835 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19836 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19837 rtx frame_reg_rtx = sp_reg_rtx;
19838 rtx cr_save_rtx = NULL_RTX;
19841 int saving_FPRs_inline;
19842 int saving_GPRs_inline;
19843 int using_store_multiple;
19844 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19845 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19846 && call_used_regs[STATIC_CHAIN_REGNUM]);
19847 HOST_WIDE_INT sp_offset = 0;
19849 if (flag_stack_usage_info)
19850 current_function_static_stack_size = info->total_size;
19852 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19853 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19855 if (TARGET_FIX_AND_CONTINUE)
19857 /* gdb on darwin arranges to forward a function from the old
19858 address by modifying the first 5 instructions of the function
19859 to branch to the overriding function. This is necessary to
19860 permit function pointers that point to the old function to
19861 actually forward to the new function. */
19862 emit_insn (gen_nop ());
19863 emit_insn (gen_nop ());
19864 emit_insn (gen_nop ());
19865 emit_insn (gen_nop ());
19866 emit_insn (gen_nop ());
19869 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19871 reg_mode = V2SImode;
19875 strategy = info->savres_strategy;
19876 using_store_multiple = strategy & SAVRES_MULTIPLE;
19877 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19878 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19880 /* For V.4, update stack before we do any saving and set back pointer. */
19881 if (! WORLD_SAVE_P (info)
19883 && (DEFAULT_ABI == ABI_V4
19884 || crtl->calls_eh_return))
19886 bool need_r11 = (TARGET_SPE
19887 ? (!saving_GPRs_inline
19888 && info->spe_64bit_regs_used == 0)
19889 : (!saving_FPRs_inline || !saving_GPRs_inline));
19890 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19892 if (info->total_size < 32767)
19893 sp_offset = info->total_size;
19895 frame_reg_rtx = copy_reg;
19896 else if (info->cr_save_p
19898 || info->first_fp_reg_save < 64
19899 || info->first_gp_reg_save < 32
19900 || info->altivec_size != 0
19901 || info->vrsave_mask != 0
19902 || crtl->calls_eh_return)
19904 copy_reg = frame_ptr_rtx;
19905 frame_reg_rtx = copy_reg;
19909 /* The prologue won't be saving any regs so there is no need
19910 to set up a frame register to access any frame save area.
19911 We also won't be using sp_offset anywhere below, but set
19912 the correct value anyway to protect against future
19913 changes to this function. */
19914 sp_offset = info->total_size;
19916 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19917 if (frame_reg_rtx != sp_reg_rtx)
19918 rs6000_emit_stack_tie ();
19921 /* Handle world saves specially here. */
19922 if (WORLD_SAVE_P (info))
19929 /* save_world expects lr in r0. */
19930 reg0 = gen_rtx_REG (Pmode, 0);
19931 if (info->lr_save_p)
19933 insn = emit_move_insn (reg0,
19934 gen_rtx_REG (Pmode, LR_REGNO));
19935 RTX_FRAME_RELATED_P (insn) = 1;
19938 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19939 assumptions about the offsets of various bits of the stack
19941 gcc_assert (info->gp_save_offset == -220
19942 && info->fp_save_offset == -144
19943 && info->lr_save_offset == 8
19944 && info->cr_save_offset == 4
19947 && (!crtl->calls_eh_return
19948 || info->ehrd_offset == -432)
19949 && info->vrsave_save_offset == -224
19950 && info->altivec_save_offset == -416);
19952 treg = gen_rtx_REG (SImode, 11);
19953 emit_move_insn (treg, GEN_INT (-info->total_size));
19955 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19956 in R11. It also clobbers R12, so beware! */
19958 /* Preserve CR2 for save_world prologues */
19960 sz += 32 - info->first_gp_reg_save;
19961 sz += 64 - info->first_fp_reg_save;
19962 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19963 p = rtvec_alloc (sz);
19965 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19966 gen_rtx_REG (SImode,
19968 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19969 gen_rtx_SYMBOL_REF (Pmode,
19971 /* We do floats first so that the instruction pattern matches
19973 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19975 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19976 ? DFmode : SFmode),
19977 info->first_fp_reg_save + i);
19978 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19979 GEN_INT (info->fp_save_offset
19980 + sp_offset + 8 * i));
19981 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19982 ? DFmode : SFmode), addr);
19984 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19986 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19988 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19989 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19990 GEN_INT (info->altivec_save_offset
19991 + sp_offset + 16 * i));
19992 rtx mem = gen_frame_mem (V4SImode, addr);
19994 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19996 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19998 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19999 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20000 GEN_INT (info->gp_save_offset
20001 + sp_offset + reg_size * i));
20002 rtx mem = gen_frame_mem (reg_mode, addr);
20004 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20008 /* CR register traditionally saved as CR2. */
20009 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20010 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20011 GEN_INT (info->cr_save_offset
20013 rtx mem = gen_frame_mem (reg_mode, addr);
20015 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20017 /* Explain about use of R0. */
20018 if (info->lr_save_p)
20020 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20021 GEN_INT (info->lr_save_offset
20023 rtx mem = gen_frame_mem (reg_mode, addr);
20025 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20027 /* Explain what happens to the stack pointer. */
20029 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20030 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20033 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20034 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20035 treg, GEN_INT (-info->total_size));
20036 sp_offset = info->total_size;
20039 /* If we use the link register, get it into r0. */
20040 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20042 rtx addr, reg, mem;
20044 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20045 gen_rtx_REG (Pmode, LR_REGNO));
20046 RTX_FRAME_RELATED_P (insn) = 1;
20048 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20049 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20051 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20052 GEN_INT (info->lr_save_offset + sp_offset));
20053 reg = gen_rtx_REG (Pmode, 0);
20054 mem = gen_rtx_MEM (Pmode, addr);
20055 /* This should not be of rs6000_sr_alias_set, because of
20056 __builtin_return_address. */
20058 insn = emit_move_insn (mem, reg);
20059 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20060 NULL_RTX, NULL_RTX);
20064 /* If we need to save CR, put it into r12 or r11. */
20065 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20070 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20072 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20073 RTX_FRAME_RELATED_P (insn) = 1;
20074 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20075 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20076 But that's OK. All we have to do is specify that _one_ condition
20077 code register is saved in this stack slot. The thrower's epilogue
20078 will then restore all the call-saved registers.
20079 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20080 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20081 gen_rtx_REG (SImode, CR2_REGNO));
20082 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20085 /* Do any required saving of fpr's. If only one or two to save, do
20086 it ourselves. Otherwise, call function. */
20087 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20090 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20091 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20092 && ! call_used_regs[info->first_fp_reg_save+i]))
20093 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20094 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20096 info->first_fp_reg_save + i,
20097 info->fp_save_offset + sp_offset + 8 * i,
20100 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20104 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20105 info->fp_save_offset + sp_offset,
20107 /*savep=*/true, /*gpr=*/false,
20109 & SAVE_NOINLINE_FPRS_SAVES_LR)
20111 insn = emit_insn (par);
20112 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20113 NULL_RTX, NULL_RTX);
20116 /* Save GPRs. This is done as a PARALLEL if we are using
20117 the store-multiple instructions. */
20118 if (!WORLD_SAVE_P (info)
20120 && info->spe_64bit_regs_used != 0
20121 && info->first_gp_reg_save != 32)
20124 rtx spe_save_area_ptr;
20126 /* Determine whether we can address all of the registers that need
20127 to be saved with an offset from the stack pointer that fits in
20128 the small const field for SPE memory instructions. */
20129 int spe_regs_addressable_via_sp
20130 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20131 + (32 - info->first_gp_reg_save - 1) * reg_size)
20132 && saving_GPRs_inline);
20135 if (spe_regs_addressable_via_sp)
20137 spe_save_area_ptr = frame_reg_rtx;
20138 spe_offset = info->spe_gp_save_offset + sp_offset;
20142 /* Make r11 point to the start of the SPE save area. We need
20143 to be careful here if r11 is holding the static chain. If
20144 it is, then temporarily save it in r0. We would use r0 as
20145 our base register here, but using r0 as a base register in
20146 loads and stores means something different from what we
20148 int ool_adjust = (saving_GPRs_inline
20150 : (info->first_gp_reg_save
20151 - (FIRST_SAVRES_REGISTER+1))*8);
20152 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20153 + sp_offset - ool_adjust);
20155 if (using_static_chain_p)
20157 rtx r0 = gen_rtx_REG (Pmode, 0);
20158 gcc_assert (info->first_gp_reg_save > 11);
20160 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20163 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20164 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20166 GEN_INT (offset)));
20167 /* We need to make sure the move to r11 gets noted for
20168 properly outputting unwind information. */
20169 if (!saving_GPRs_inline)
20170 rs6000_frame_related (insn, frame_reg_rtx, offset,
20171 NULL_RTX, NULL_RTX);
20175 if (saving_GPRs_inline)
20177 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20178 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20180 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20181 rtx offset, addr, mem;
20183 /* We're doing all this to ensure that the offset fits into
20184 the immediate offset of 'evstdd'. */
20185 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20187 offset = GEN_INT (reg_size * i + spe_offset);
20188 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20189 mem = gen_rtx_MEM (V2SImode, addr);
20191 insn = emit_move_insn (mem, reg);
20193 rs6000_frame_related (insn, spe_save_area_ptr,
20194 info->spe_gp_save_offset
20195 + sp_offset + reg_size * i,
20196 offset, const0_rtx);
20203 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20205 /*savep=*/true, /*gpr=*/true,
20207 insn = emit_insn (par);
20208 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20209 NULL_RTX, NULL_RTX);
20213 /* Move the static chain pointer back. */
20214 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20215 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20217 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20221 /* Need to adjust r11 (r12) if we saved any FPRs. */
20222 if (info->first_fp_reg_save != 64)
20224 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20226 rtx offset = GEN_INT (sp_offset
20227 + (-8 * (64-info->first_fp_reg_save)));
20228 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20231 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20232 info->gp_save_offset + sp_offset,
20234 /*savep=*/true, /*gpr=*/true,
20236 & SAVE_NOINLINE_GPRS_SAVES_LR)
20238 insn = emit_insn (par);
20239 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20240 NULL_RTX, NULL_RTX);
20242 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20246 p = rtvec_alloc (32 - info->first_gp_reg_save);
20247 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20249 rtx addr, reg, mem;
20250 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20251 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20252 GEN_INT (info->gp_save_offset
20255 mem = gen_frame_mem (reg_mode, addr);
20257 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20259 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20260 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20261 NULL_RTX, NULL_RTX);
20263 else if (!WORLD_SAVE_P (info))
20266 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20267 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20269 rtx addr, reg, mem;
20270 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20272 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20273 GEN_INT (info->gp_save_offset
20276 mem = gen_frame_mem (reg_mode, addr);
20278 insn = emit_move_insn (mem, reg);
20279 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20280 NULL_RTX, NULL_RTX);
20284 /* ??? There's no need to emit actual instructions here, but it's the
20285 easiest way to get the frame unwind information emitted. */
20286 if (crtl->calls_eh_return)
20288 unsigned int i, regno;
20292 regno = EH_RETURN_DATA_REGNO (i);
20293 if (regno == INVALID_REGNUM)
20296 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20297 info->ehrd_offset + sp_offset
20298 + reg_size * (int) i,
20303 /* In AIX ABI we need to make sure r2 is really saved. */
20304 if (TARGET_AIX && crtl->calls_eh_return)
20306 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20307 long toc_restore_insn;
20309 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20310 || frame_reg_rtx == sp_reg_rtx);
20311 tmp_reg = gen_rtx_REG (Pmode, 11);
20312 tmp_reg_si = gen_rtx_REG (SImode, 11);
20313 if (using_static_chain_p)
20314 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20315 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20316 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20317 /* Peek at instruction to which this function returns. If it's
20318 restoring r2, then we know we've already saved r2. We can't
20319 unconditionally save r2 because the value we have will already
20320 be updated if we arrived at this function via a plt call or
20321 toc adjusting stub. */
20322 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20323 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20324 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20325 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20326 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20327 validate_condition_mode (EQ, CCUNSmode);
20328 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20329 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20330 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20331 toc_save_done = gen_label_rtx ();
20332 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20333 gen_rtx_EQ (VOIDmode, compare_result,
20335 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20337 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20338 JUMP_LABEL (jump) = toc_save_done;
20339 LABEL_NUSES (toc_save_done) += 1;
20341 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20342 sp_offset + 5 * reg_size, info->total_size);
20343 emit_label (toc_save_done);
20344 if (using_static_chain_p)
20345 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20348 /* Save CR if we use any that must be preserved. */
20349 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20351 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20352 GEN_INT (info->cr_save_offset + sp_offset));
20353 rtx mem = gen_frame_mem (SImode, addr);
20354 /* See the large comment above about why CR2_REGNO is used. */
20355 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20357 /* If r12 was used to hold the original sp, copy cr into r0 now
20359 if (REGNO (frame_reg_rtx) == 12)
20363 cr_save_rtx = gen_rtx_REG (SImode, 0);
20364 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20365 RTX_FRAME_RELATED_P (insn) = 1;
20366 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20367 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20369 insn = emit_move_insn (mem, cr_save_rtx);
20371 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20372 NULL_RTX, NULL_RTX);
20375 /* Update stack and set back pointer unless this is V.4,
20376 for which it was done previously. */
20377 if (!WORLD_SAVE_P (info) && info->push_p
20378 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20380 rtx copy_reg = NULL;
20382 if (info->total_size < 32767)
20383 sp_offset = info->total_size;
20384 else if (info->altivec_size != 0
20385 || info->vrsave_mask != 0)
20387 copy_reg = frame_ptr_rtx;
20388 frame_reg_rtx = copy_reg;
20391 sp_offset = info->total_size;
20392 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20393 if (frame_reg_rtx != sp_reg_rtx)
20394 rs6000_emit_stack_tie ();
20397 /* Set frame pointer, if needed. */
20398 if (frame_pointer_needed)
20400 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20402 RTX_FRAME_RELATED_P (insn) = 1;
20405 /* Save AltiVec registers if needed. Save here because the red zone does
20406 not include AltiVec registers. */
20407 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20411 /* There should be a non inline version of this, for when we
20412 are saving lots of vector registers. */
20413 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20414 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20416 rtx areg, savereg, mem;
20419 offset = info->altivec_save_offset + sp_offset
20420 + 16 * (i - info->first_altivec_reg_save);
20422 savereg = gen_rtx_REG (V4SImode, i);
20424 areg = gen_rtx_REG (Pmode, 0);
20425 emit_move_insn (areg, GEN_INT (offset));
20427 /* AltiVec addressing mode is [reg+reg]. */
20428 mem = gen_frame_mem (V4SImode,
20429 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20431 insn = emit_move_insn (mem, savereg);
20433 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20434 areg, GEN_INT (offset));
20438 /* VRSAVE is a bit vector representing which AltiVec registers
20439 are used. The OS uses this to determine which vector
20440 registers to save on a context switch. We need to save
20441 VRSAVE on the stack frame, add whatever AltiVec registers we
20442 used in this function, and do the corresponding magic in the
20445 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20446 && info->vrsave_mask != 0)
20448 rtx reg, mem, vrsave;
20451 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20452 as frame_reg_rtx and r11 as the static chain pointer for
20453 nested functions. */
20454 reg = gen_rtx_REG (SImode, 0);
20455 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20457 emit_insn (gen_get_vrsave_internal (reg));
20459 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20461 if (!WORLD_SAVE_P (info))
20464 offset = info->vrsave_save_offset + sp_offset;
20465 mem = gen_frame_mem (SImode,
20466 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20467 GEN_INT (offset)));
20468 insn = emit_move_insn (mem, reg);
20471 /* Include the registers in the mask. */
20472 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20474 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20477 if (TARGET_SINGLE_PIC_BASE)
20478 return; /* Do not set PIC register */
20480 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20481 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20482 || (DEFAULT_ABI == ABI_V4
20483 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20484 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20486 /* If emit_load_toc_table will use the link register, we need to save
20487 it. We use R12 for this purpose because emit_load_toc_table
20488 can use register 0. This allows us to use a plain 'blr' to return
20489 from the procedure more often. */
20490 int save_LR_around_toc_setup = (TARGET_ELF
20491 && DEFAULT_ABI != ABI_AIX
20493 && ! info->lr_save_p
20494 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20495 if (save_LR_around_toc_setup)
20497 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20499 insn = emit_move_insn (frame_ptr_rtx, lr);
20500 RTX_FRAME_RELATED_P (insn) = 1;
20502 rs6000_emit_load_toc_table (TRUE);
20504 insn = emit_move_insn (lr, frame_ptr_rtx);
20505 RTX_FRAME_RELATED_P (insn) = 1;
20508 rs6000_emit_load_toc_table (TRUE);
20512 if (DEFAULT_ABI == ABI_DARWIN
20513 && flag_pic && crtl->uses_pic_offset_table)
20515 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20516 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20518 /* Save and restore LR locally around this call (in R0). */
20519 if (!info->lr_save_p)
20520 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20522 emit_insn (gen_load_macho_picbase (src));
20524 emit_move_insn (gen_rtx_REG (Pmode,
20525 RS6000_PIC_OFFSET_TABLE_REGNUM),
20528 if (!info->lr_save_p)
20529 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20534 /* Write function prologue. */
20537 rs6000_output_function_prologue (FILE *file,
20538 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20540 rs6000_stack_t *info = rs6000_stack_info ();
20542 if (TARGET_DEBUG_STACK)
20543 debug_stack_info (info);
20545 /* Write .extern for any function we will call to save and restore
20547 if (info->first_fp_reg_save < 64)
20550 int regno = info->first_fp_reg_save - 32;
20552 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20554 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20555 /*gpr=*/false, /*lr=*/false);
20556 fprintf (file, "\t.extern %s\n", name);
20558 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20560 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20561 /*gpr=*/false, /*lr=*/true);
20562 fprintf (file, "\t.extern %s\n", name);
20566 /* Write .extern for AIX common mode routines, if needed. */
20567 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20569 fputs ("\t.extern __mulh\n", file);
20570 fputs ("\t.extern __mull\n", file);
20571 fputs ("\t.extern __divss\n", file);
20572 fputs ("\t.extern __divus\n", file);
20573 fputs ("\t.extern __quoss\n", file);
20574 fputs ("\t.extern __quous\n", file);
20575 common_mode_defined = 1;
20578 if (! HAVE_prologue)
20584 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20585 the "toplevel" insn chain. */
20586 emit_note (NOTE_INSN_DELETED);
20587 rs6000_emit_prologue ();
20588 emit_note (NOTE_INSN_DELETED);
20590 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20594 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20596 INSN_ADDRESSES_NEW (insn, addr);
20601 prologue = get_insns ();
20604 if (TARGET_DEBUG_STACK)
20605 debug_rtx_list (prologue, 100);
20607 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20611 rs6000_pic_labelno++;
20614 /* Non-zero if vmx regs are restored before the frame pop, zero if
20615 we restore after the pop when possible. */
20616 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20618 /* Reload CR from REG. */
20621 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20626 if (using_mfcr_multiple)
20628 for (i = 0; i < 8; i++)
20629 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20631 gcc_assert (count);
20634 if (using_mfcr_multiple && count > 1)
20639 p = rtvec_alloc (count);
20642 for (i = 0; i < 8; i++)
20643 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20645 rtvec r = rtvec_alloc (2);
20646 RTVEC_ELT (r, 0) = reg;
20647 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20648 RTVEC_ELT (p, ndx) =
20649 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20650 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20653 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20654 gcc_assert (ndx == count);
20657 for (i = 0; i < 8; i++)
20658 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20660 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20666 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20667 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20668 below stack pointer not cloberred by signals. */
20671 offset_below_red_zone_p (HOST_WIDE_INT offset)
20673 return offset < (DEFAULT_ABI == ABI_V4
20675 : TARGET_32BIT ? -220 : -288);
20678 /* Emit function epilogue as insns. */
20681 rs6000_emit_epilogue (int sibcall)
20683 rs6000_stack_t *info;
20684 int restoring_GPRs_inline;
20685 int restoring_FPRs_inline;
20686 int using_load_multiple;
20687 int using_mtcr_multiple;
20688 int use_backchain_to_restore_sp;
20692 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20693 rtx frame_reg_rtx = sp_reg_rtx;
20694 rtx cfa_restores = NULL_RTX;
20696 rtx cr_save_reg = NULL_RTX;
20697 enum machine_mode reg_mode = Pmode;
20698 int reg_size = TARGET_32BIT ? 4 : 8;
20701 info = rs6000_stack_info ();
20703 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20705 reg_mode = V2SImode;
20709 strategy = info->savres_strategy;
20710 using_load_multiple = strategy & SAVRES_MULTIPLE;
20711 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20712 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20713 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20714 || rs6000_cpu == PROCESSOR_PPC603
20715 || rs6000_cpu == PROCESSOR_PPC750
20717 /* Restore via the backchain when we have a large frame, since this
20718 is more efficient than an addis, addi pair. The second condition
20719 here will not trigger at the moment; We don't actually need a
20720 frame pointer for alloca, but the generic parts of the compiler
20721 give us one anyway. */
20722 use_backchain_to_restore_sp = (info->total_size > 32767
20723 || info->total_size
20724 + (info->lr_save_p ? info->lr_save_offset : 0)
20726 || (cfun->calls_alloca
20727 && !frame_pointer_needed));
20728 restore_lr = (info->lr_save_p
20729 && (restoring_FPRs_inline
20730 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20731 && (restoring_GPRs_inline
20732 || info->first_fp_reg_save < 64));
20734 if (WORLD_SAVE_P (info))
20738 const char *alloc_rname;
20741 /* eh_rest_world_r10 will return to the location saved in the LR
20742 stack slot (which is not likely to be our caller.)
20743 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20744 rest_world is similar, except any R10 parameter is ignored.
20745 The exception-handling stuff that was here in 2.95 is no
20746 longer necessary. */
20750 + 32 - info->first_gp_reg_save
20751 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20752 + 63 + 1 - info->first_fp_reg_save);
20754 strcpy (rname, ((crtl->calls_eh_return) ?
20755 "*eh_rest_world_r10" : "*rest_world"));
20756 alloc_rname = ggc_strdup (rname);
20759 RTVEC_ELT (p, j++) = ret_rtx;
20760 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20761 gen_rtx_REG (Pmode,
20764 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20765 /* The instruction pattern requires a clobber here;
20766 it is shared with the restVEC helper. */
20768 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20771 /* CR register traditionally saved as CR2. */
20772 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20773 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20774 GEN_INT (info->cr_save_offset));
20775 rtx mem = gen_frame_mem (reg_mode, addr);
20777 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20780 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20782 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20783 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20784 GEN_INT (info->gp_save_offset
20786 rtx mem = gen_frame_mem (reg_mode, addr);
20788 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20790 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20792 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20793 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20794 GEN_INT (info->altivec_save_offset
20796 rtx mem = gen_frame_mem (V4SImode, addr);
20798 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20800 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20802 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20803 ? DFmode : SFmode),
20804 info->first_fp_reg_save + i);
20805 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20806 GEN_INT (info->fp_save_offset
20808 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20809 ? DFmode : SFmode), addr);
20811 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20814 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20816 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20818 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20820 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20822 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20823 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20828 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20830 sp_offset = info->total_size;
20832 /* Restore AltiVec registers if we must do so before adjusting the
20834 if (TARGET_ALTIVEC_ABI
20835 && info->altivec_size != 0
20836 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20837 || (DEFAULT_ABI != ABI_V4
20838 && offset_below_red_zone_p (info->altivec_save_offset))))
20842 if (use_backchain_to_restore_sp)
20844 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20845 emit_move_insn (frame_reg_rtx,
20846 gen_rtx_MEM (Pmode, sp_reg_rtx));
20849 else if (frame_pointer_needed)
20850 frame_reg_rtx = hard_frame_pointer_rtx;
20852 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20853 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20855 rtx addr, areg, mem, reg;
20857 areg = gen_rtx_REG (Pmode, 0);
20859 (areg, GEN_INT (info->altivec_save_offset
20861 + 16 * (i - info->first_altivec_reg_save)));
20863 /* AltiVec addressing mode is [reg+reg]. */
20864 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20865 mem = gen_frame_mem (V4SImode, addr);
20867 reg = gen_rtx_REG (V4SImode, i);
20868 emit_move_insn (reg, mem);
20869 if (offset_below_red_zone_p (info->altivec_save_offset
20870 + (i - info->first_altivec_reg_save)
20872 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20877 /* Restore VRSAVE if we must do so before adjusting the stack. */
20879 && TARGET_ALTIVEC_VRSAVE
20880 && info->vrsave_mask != 0
20881 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20882 || (DEFAULT_ABI != ABI_V4
20883 && offset_below_red_zone_p (info->vrsave_save_offset))))
20885 rtx addr, mem, reg;
20887 if (frame_reg_rtx == sp_reg_rtx)
20889 if (use_backchain_to_restore_sp)
20891 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20892 emit_move_insn (frame_reg_rtx,
20893 gen_rtx_MEM (Pmode, sp_reg_rtx));
20896 else if (frame_pointer_needed)
20897 frame_reg_rtx = hard_frame_pointer_rtx;
20900 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20901 GEN_INT (info->vrsave_save_offset + sp_offset));
20902 mem = gen_frame_mem (SImode, addr);
20903 reg = gen_rtx_REG (SImode, 12);
20904 emit_move_insn (reg, mem);
20906 emit_insn (generate_set_vrsave (reg, info, 1));
20910 /* If we have a large stack frame, restore the old stack pointer
20911 using the backchain. */
20912 if (use_backchain_to_restore_sp)
20914 if (frame_reg_rtx == sp_reg_rtx)
20916 /* Under V.4, don't reset the stack pointer until after we're done
20917 loading the saved registers. */
20918 if (DEFAULT_ABI == ABI_V4)
20919 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20921 insn = emit_move_insn (frame_reg_rtx,
20922 gen_rtx_MEM (Pmode, sp_reg_rtx));
20925 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20926 && DEFAULT_ABI == ABI_V4)
20927 /* frame_reg_rtx has been set up by the altivec restore. */
20931 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20932 frame_reg_rtx = sp_reg_rtx;
20935 /* If we have a frame pointer, we can restore the old stack pointer
20937 else if (frame_pointer_needed)
20939 frame_reg_rtx = sp_reg_rtx;
20940 if (DEFAULT_ABI == ABI_V4)
20941 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20942 /* Prevent reordering memory accesses against stack pointer restore. */
20943 else if (cfun->calls_alloca
20944 || offset_below_red_zone_p (-info->total_size))
20946 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20947 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20948 MEM_NOTRAP_P (mem1) = 1;
20949 MEM_NOTRAP_P (mem2) = 1;
20950 emit_insn (gen_frame_tie (mem1, mem2));
20953 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20954 GEN_INT (info->total_size)));
20957 else if (info->push_p
20958 && DEFAULT_ABI != ABI_V4
20959 && !crtl->calls_eh_return)
20961 /* Prevent reordering memory accesses against stack pointer restore. */
20962 if (cfun->calls_alloca
20963 || offset_below_red_zone_p (-info->total_size))
20965 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20966 MEM_NOTRAP_P (mem) = 1;
20967 emit_insn (gen_stack_tie (mem));
20969 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20970 GEN_INT (info->total_size)));
20973 if (insn && frame_reg_rtx == sp_reg_rtx)
20977 REG_NOTES (insn) = cfa_restores;
20978 cfa_restores = NULL_RTX;
20980 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20981 RTX_FRAME_RELATED_P (insn) = 1;
20984 /* Restore AltiVec registers if we have not done so already. */
20985 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20986 && TARGET_ALTIVEC_ABI
20987 && info->altivec_size != 0
20988 && (DEFAULT_ABI == ABI_V4
20989 || !offset_below_red_zone_p (info->altivec_save_offset)))
20993 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20994 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20996 rtx addr, areg, mem, reg;
20998 areg = gen_rtx_REG (Pmode, 0);
21000 (areg, GEN_INT (info->altivec_save_offset
21002 + 16 * (i - info->first_altivec_reg_save)));
21004 /* AltiVec addressing mode is [reg+reg]. */
21005 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21006 mem = gen_frame_mem (V4SImode, addr);
21008 reg = gen_rtx_REG (V4SImode, i);
21009 emit_move_insn (reg, mem);
21010 if (DEFAULT_ABI == ABI_V4)
21011 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21016 /* Restore VRSAVE if we have not done so already. */
21017 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21019 && TARGET_ALTIVEC_VRSAVE
21020 && info->vrsave_mask != 0
21021 && (DEFAULT_ABI == ABI_V4
21022 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21024 rtx addr, mem, reg;
21026 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21027 GEN_INT (info->vrsave_save_offset + sp_offset));
21028 mem = gen_frame_mem (SImode, addr);
21029 reg = gen_rtx_REG (SImode, 12);
21030 emit_move_insn (reg, mem);
21032 emit_insn (generate_set_vrsave (reg, info, 1));
21035 /* Get the old lr if we saved it. If we are restoring registers
21036 out-of-line, then the out-of-line routines can do this for us. */
21037 if (restore_lr && restoring_GPRs_inline)
21039 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21040 info->lr_save_offset + sp_offset);
21042 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21045 /* Get the old cr if we saved it. */
21046 if (info->cr_save_p)
21048 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21049 GEN_INT (info->cr_save_offset + sp_offset));
21050 rtx mem = gen_frame_mem (SImode, addr);
21052 cr_save_reg = gen_rtx_REG (SImode,
21053 DEFAULT_ABI == ABI_AIX
21054 && !restoring_GPRs_inline
21055 && info->first_fp_reg_save < 64
21057 emit_move_insn (cr_save_reg, mem);
21060 /* Set LR here to try to overlap restores below. LR is always saved
21061 above incoming stack, so it never needs REG_CFA_RESTORE. */
21062 if (restore_lr && restoring_GPRs_inline)
21063 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21064 gen_rtx_REG (Pmode, 0));
21066 /* Load exception handler data registers, if needed. */
21067 if (crtl->calls_eh_return)
21069 unsigned int i, regno;
21073 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21074 GEN_INT (sp_offset + 5 * reg_size));
21075 rtx mem = gen_frame_mem (reg_mode, addr);
21077 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21084 regno = EH_RETURN_DATA_REGNO (i);
21085 if (regno == INVALID_REGNUM)
21088 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21089 info->ehrd_offset + sp_offset
21090 + reg_size * (int) i);
21092 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21096 /* Restore GPRs. This is done as a PARALLEL if we are using
21097 the load-multiple instructions. */
21099 && info->spe_64bit_regs_used != 0
21100 && info->first_gp_reg_save != 32)
21102 /* Determine whether we can address all of the registers that need
21103 to be saved with an offset from the stack pointer that fits in
21104 the small const field for SPE memory instructions. */
21105 int spe_regs_addressable_via_sp
21106 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21107 + (32 - info->first_gp_reg_save - 1) * reg_size)
21108 && restoring_GPRs_inline);
21111 if (spe_regs_addressable_via_sp)
21112 spe_offset = info->spe_gp_save_offset + sp_offset;
21115 rtx old_frame_reg_rtx = frame_reg_rtx;
21116 /* Make r11 point to the start of the SPE save area. We worried about
21117 not clobbering it when we were saving registers in the prologue.
21118 There's no need to worry here because the static chain is passed
21119 anew to every function. */
21120 int ool_adjust = (restoring_GPRs_inline
21122 : (info->first_gp_reg_save
21123 - (FIRST_SAVRES_REGISTER+1))*8);
21125 if (frame_reg_rtx == sp_reg_rtx)
21126 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21127 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21128 GEN_INT (info->spe_gp_save_offset
21131 /* Keep the invariant that frame_reg_rtx + sp_offset points
21132 at the top of the stack frame. */
21133 sp_offset = -info->spe_gp_save_offset;
21138 if (restoring_GPRs_inline)
21140 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21141 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21143 rtx offset, addr, mem, reg;
21145 /* We're doing all this to ensure that the immediate offset
21146 fits into the immediate field of 'evldd'. */
21147 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21149 offset = GEN_INT (spe_offset + reg_size * i);
21150 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21151 mem = gen_rtx_MEM (V2SImode, addr);
21152 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21154 insn = emit_move_insn (reg, mem);
21155 if (DEFAULT_ABI == ABI_V4)
21157 if (frame_pointer_needed
21158 && info->first_gp_reg_save + i
21159 == HARD_FRAME_POINTER_REGNUM)
21161 add_reg_note (insn, REG_CFA_DEF_CFA,
21162 plus_constant (frame_reg_rtx,
21164 RTX_FRAME_RELATED_P (insn) = 1;
21167 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21176 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21178 /*savep=*/false, /*gpr=*/true,
21180 emit_jump_insn (par);
21181 /* We don't want anybody else emitting things after we jumped
21186 else if (!restoring_GPRs_inline)
21188 /* We are jumping to an out-of-line function. */
21189 bool can_use_exit = info->first_fp_reg_save == 64;
21192 /* Emit stack reset code if we need it. */
21194 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21195 sp_offset, can_use_exit);
21198 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21201 GEN_INT (sp_offset - info->fp_size)));
21202 if (REGNO (frame_reg_rtx) == 11)
21203 sp_offset += info->fp_size;
21206 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21207 info->gp_save_offset, reg_mode,
21208 /*savep=*/false, /*gpr=*/true,
21209 /*lr=*/can_use_exit);
21213 if (info->cr_save_p)
21215 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21216 if (DEFAULT_ABI == ABI_V4)
21218 = alloc_reg_note (REG_CFA_RESTORE,
21219 gen_rtx_REG (SImode, CR2_REGNO),
21223 emit_jump_insn (par);
21225 /* We don't want anybody else emitting things after we jumped
21230 insn = emit_insn (par);
21231 if (DEFAULT_ABI == ABI_V4)
21233 if (frame_pointer_needed)
21235 add_reg_note (insn, REG_CFA_DEF_CFA,
21236 plus_constant (frame_reg_rtx, sp_offset));
21237 RTX_FRAME_RELATED_P (insn) = 1;
21240 for (i = info->first_gp_reg_save; i < 32; i++)
21242 = alloc_reg_note (REG_CFA_RESTORE,
21243 gen_rtx_REG (reg_mode, i), cfa_restores);
21246 else if (using_load_multiple)
21249 p = rtvec_alloc (32 - info->first_gp_reg_save);
21250 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21252 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21253 GEN_INT (info->gp_save_offset
21256 rtx mem = gen_frame_mem (reg_mode, addr);
21257 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21259 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21260 if (DEFAULT_ABI == ABI_V4)
21261 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21264 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21265 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21267 add_reg_note (insn, REG_CFA_DEF_CFA,
21268 plus_constant (frame_reg_rtx, sp_offset));
21269 RTX_FRAME_RELATED_P (insn) = 1;
21274 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21275 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21277 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21278 GEN_INT (info->gp_save_offset
21281 rtx mem = gen_frame_mem (reg_mode, addr);
21282 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21284 insn = emit_move_insn (reg, mem);
21285 if (DEFAULT_ABI == ABI_V4)
21287 if (frame_pointer_needed
21288 && info->first_gp_reg_save + i
21289 == HARD_FRAME_POINTER_REGNUM)
21291 add_reg_note (insn, REG_CFA_DEF_CFA,
21292 plus_constant (frame_reg_rtx, sp_offset));
21293 RTX_FRAME_RELATED_P (insn) = 1;
21296 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21302 if (restore_lr && !restoring_GPRs_inline)
21304 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21305 info->lr_save_offset + sp_offset);
21307 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21308 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21309 gen_rtx_REG (Pmode, 0));
21312 /* Restore fpr's if we need to do it without calling a function. */
21313 if (restoring_FPRs_inline)
21314 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21315 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21316 && ! call_used_regs[info->first_fp_reg_save+i]))
21318 rtx addr, mem, reg;
21319 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21320 GEN_INT (info->fp_save_offset
21323 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21324 ? DFmode : SFmode), addr);
21325 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21326 ? DFmode : SFmode),
21327 info->first_fp_reg_save + i);
21329 emit_move_insn (reg, mem);
21330 if (DEFAULT_ABI == ABI_V4)
21331 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21335 /* If we saved cr, restore it here. Just those that were used. */
21336 if (info->cr_save_p)
21338 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21339 if (DEFAULT_ABI == ABI_V4)
21341 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21345 /* If this is V.4, unwind the stack pointer after all of the loads
21347 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21348 sp_offset, !restoring_FPRs_inline);
21353 REG_NOTES (insn) = cfa_restores;
21354 cfa_restores = NULL_RTX;
21356 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21357 RTX_FRAME_RELATED_P (insn) = 1;
21360 if (crtl->calls_eh_return)
21362 rtx sa = EH_RETURN_STACKADJ_RTX;
21363 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21369 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21370 if (! restoring_FPRs_inline)
21371 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21373 p = rtvec_alloc (2);
21375 RTVEC_ELT (p, 0) = ret_rtx;
21376 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21377 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21378 : gen_rtx_CLOBBER (VOIDmode,
21379 gen_rtx_REG (Pmode, 65)));
21381 /* If we have to restore more than two FP registers, branch to the
21382 restore function. It will return to our caller. */
21383 if (! restoring_FPRs_inline)
21388 sym = rs6000_savres_routine_sym (info,
21392 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21393 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21394 gen_rtx_REG (Pmode,
21395 DEFAULT_ABI == ABI_AIX
21397 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21400 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21401 GEN_INT (info->fp_save_offset + 8*i));
21402 mem = gen_frame_mem (DFmode, addr);
21404 RTVEC_ELT (p, i+4) =
21405 gen_rtx_SET (VOIDmode,
21406 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21411 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21415 /* Write function epilogue. */
21418 rs6000_output_function_epilogue (FILE *file,
21419 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21421 if (! HAVE_epilogue)
21423 rtx insn = get_last_insn ();
21424 /* If the last insn was a BARRIER, we don't have to write anything except
21425 the trace table. */
21426 if (GET_CODE (insn) == NOTE)
21427 insn = prev_nonnote_insn (insn);
21428 if (insn == 0 || GET_CODE (insn) != BARRIER)
21430 /* This is slightly ugly, but at least we don't have two
21431 copies of the epilogue-emitting code. */
21434 /* A NOTE_INSN_DELETED is supposed to be at the start
21435 and end of the "toplevel" insn chain. */
21436 emit_note (NOTE_INSN_DELETED);
21437 rs6000_emit_epilogue (FALSE);
21438 emit_note (NOTE_INSN_DELETED);
21440 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21444 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21446 INSN_ADDRESSES_NEW (insn, addr);
21451 if (TARGET_DEBUG_STACK)
21452 debug_rtx_list (get_insns (), 100);
21453 final (get_insns (), file, FALSE);
21459 macho_branch_islands ();
21460 /* Mach-O doesn't support labels at the end of objects, so if
21461 it looks like we might want one, insert a NOP. */
21463 rtx insn = get_last_insn ();
21466 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21467 insn = PREV_INSN (insn);
21471 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21472 fputs ("\tnop\n", file);
21476 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21479 We don't output a traceback table if -finhibit-size-directive was
21480 used. The documentation for -finhibit-size-directive reads
21481 ``don't output a @code{.size} assembler directive, or anything
21482 else that would cause trouble if the function is split in the
21483 middle, and the two halves are placed at locations far apart in
21484 memory.'' The traceback table has this property, since it
21485 includes the offset from the start of the function to the
21486 traceback table itself.
21488 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21489 different traceback table. */
21490 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21491 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21493 const char *fname = NULL;
21494 const char *language_string = lang_hooks.name;
21495 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21497 int optional_tbtab;
21498 rs6000_stack_t *info = rs6000_stack_info ();
21500 if (rs6000_traceback == traceback_full)
21501 optional_tbtab = 1;
21502 else if (rs6000_traceback == traceback_part)
21503 optional_tbtab = 0;
21505 optional_tbtab = !optimize_size && !TARGET_ELF;
21507 if (optional_tbtab)
21509 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21510 while (*fname == '.') /* V.4 encodes . in the name */
21513 /* Need label immediately before tbtab, so we can compute
21514 its offset from the function start. */
21515 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21516 ASM_OUTPUT_LABEL (file, fname);
21519 /* The .tbtab pseudo-op can only be used for the first eight
21520 expressions, since it can't handle the possibly variable
21521 length fields that follow. However, if you omit the optional
21522 fields, the assembler outputs zeros for all optional fields
21523 anyways, giving each variable length field is minimum length
21524 (as defined in sys/debug.h). Thus we can not use the .tbtab
21525 pseudo-op at all. */
21527 /* An all-zero word flags the start of the tbtab, for debuggers
21528 that have to find it by searching forward from the entry
21529 point or from the current pc. */
21530 fputs ("\t.long 0\n", file);
21532 /* Tbtab format type. Use format type 0. */
21533 fputs ("\t.byte 0,", file);
21535 /* Language type. Unfortunately, there does not seem to be any
21536 official way to discover the language being compiled, so we
21537 use language_string.
21538 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21539 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21540 a number, so for now use 9. LTO and Go aren't assigned numbers
21541 either, so for now use 0. */
21542 if (! strcmp (language_string, "GNU C")
21543 || ! strcmp (language_string, "GNU GIMPLE")
21544 || ! strcmp (language_string, "GNU Go"))
21546 else if (! strcmp (language_string, "GNU F77")
21547 || ! strcmp (language_string, "GNU Fortran"))
21549 else if (! strcmp (language_string, "GNU Pascal"))
21551 else if (! strcmp (language_string, "GNU Ada"))
21553 else if (! strcmp (language_string, "GNU C++")
21554 || ! strcmp (language_string, "GNU Objective-C++"))
21556 else if (! strcmp (language_string, "GNU Java"))
21558 else if (! strcmp (language_string, "GNU Objective-C"))
21561 gcc_unreachable ();
21562 fprintf (file, "%d,", i);
21564 /* 8 single bit fields: global linkage (not set for C extern linkage,
21565 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21566 from start of procedure stored in tbtab, internal function, function
21567 has controlled storage, function has no toc, function uses fp,
21568 function logs/aborts fp operations. */
21569 /* Assume that fp operations are used if any fp reg must be saved. */
21570 fprintf (file, "%d,",
21571 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21573 /* 6 bitfields: function is interrupt handler, name present in
21574 proc table, function calls alloca, on condition directives
21575 (controls stack walks, 3 bits), saves condition reg, saves
21577 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21578 set up as a frame pointer, even when there is no alloca call. */
21579 fprintf (file, "%d,",
21580 ((optional_tbtab << 6)
21581 | ((optional_tbtab & frame_pointer_needed) << 5)
21582 | (info->cr_save_p << 1)
21583 | (info->lr_save_p)));
21585 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21587 fprintf (file, "%d,",
21588 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21590 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21591 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21593 if (optional_tbtab)
21595 /* Compute the parameter info from the function decl argument
21598 int next_parm_info_bit = 31;
21600 for (decl = DECL_ARGUMENTS (current_function_decl);
21601 decl; decl = DECL_CHAIN (decl))
21603 rtx parameter = DECL_INCOMING_RTL (decl);
21604 enum machine_mode mode = GET_MODE (parameter);
21606 if (GET_CODE (parameter) == REG)
21608 if (SCALAR_FLOAT_MODE_P (mode))
21629 gcc_unreachable ();
21632 /* If only one bit will fit, don't or in this entry. */
21633 if (next_parm_info_bit > 0)
21634 parm_info |= (bits << (next_parm_info_bit - 1));
21635 next_parm_info_bit -= 2;
21639 fixed_parms += ((GET_MODE_SIZE (mode)
21640 + (UNITS_PER_WORD - 1))
21642 next_parm_info_bit -= 1;
21648 /* Number of fixed point parameters. */
21649 /* This is actually the number of words of fixed point parameters; thus
21650 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21651 fprintf (file, "%d,", fixed_parms);
21653 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21655 /* This is actually the number of fp registers that hold parameters;
21656 and thus the maximum value is 13. */
21657 /* Set parameters on stack bit if parameters are not in their original
21658 registers, regardless of whether they are on the stack? Xlc
21659 seems to set the bit when not optimizing. */
21660 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21662 if (! optional_tbtab)
21665 /* Optional fields follow. Some are variable length. */
21667 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21668 11 double float. */
21669 /* There is an entry for each parameter in a register, in the order that
21670 they occur in the parameter list. Any intervening arguments on the
21671 stack are ignored. If the list overflows a long (max possible length
21672 34 bits) then completely leave off all elements that don't fit. */
21673 /* Only emit this long if there was at least one parameter. */
21674 if (fixed_parms || float_parms)
21675 fprintf (file, "\t.long %d\n", parm_info);
21677 /* Offset from start of code to tb table. */
21678 fputs ("\t.long ", file);
21679 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21680 RS6000_OUTPUT_BASENAME (file, fname);
21682 rs6000_output_function_entry (file, fname);
21685 /* Interrupt handler mask. */
21686 /* Omit this long, since we never set the interrupt handler bit
21689 /* Number of CTL (controlled storage) anchors. */
21690 /* Omit this long, since the has_ctl bit is never set above. */
21692 /* Displacement into stack of each CTL anchor. */
21693 /* Omit this list of longs, because there are no CTL anchors. */
21695 /* Length of function name. */
21698 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21700 /* Function name. */
21701 assemble_string (fname, strlen (fname));
21703 /* Register for alloca automatic storage; this is always reg 31.
21704 Only emit this if the alloca bit was set above. */
21705 if (frame_pointer_needed)
21706 fputs ("\t.byte 31\n", file);
21708 fputs ("\t.align 2\n", file);
21712 /* A C compound statement that outputs the assembler code for a thunk
21713 function, used to implement C++ virtual function calls with
21714 multiple inheritance. The thunk acts as a wrapper around a virtual
21715 function, adjusting the implicit object parameter before handing
21716 control off to the real function.
21718 First, emit code to add the integer DELTA to the location that
21719 contains the incoming first argument. Assume that this argument
21720 contains a pointer, and is the one used to pass the `this' pointer
21721 in C++. This is the incoming argument *before* the function
21722 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21723 values of all other incoming arguments.
21725 After the addition, emit code to jump to FUNCTION, which is a
21726 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21727 not touch the return address. Hence returning from FUNCTION will
21728 return to whoever called the current `thunk'.
21730 The effect must be as if FUNCTION had been called directly with the
21731 adjusted first argument. This macro is responsible for emitting
21732 all of the code for a thunk function; output_function_prologue()
21733 and output_function_epilogue() are not invoked.
21735 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21736 been extracted from it.) It might possibly be useful on some
21737 targets, but probably not.
21739 If you do not define this macro, the target-independent code in the
21740 C++ frontend will generate a less efficient heavyweight thunk that
21741 calls FUNCTION instead of jumping to it. The generic approach does
21742 not support varargs. */
21745 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21746 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21749 rtx this_rtx, insn, funexp;
21751 reload_completed = 1;
21752 epilogue_completed = 1;
21754 /* Mark the end of the (empty) prologue. */
21755 emit_note (NOTE_INSN_PROLOGUE_END);
21757 /* Find the "this" pointer. If the function returns a structure,
21758 the structure return pointer is in r3. */
21759 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21760 this_rtx = gen_rtx_REG (Pmode, 4);
21762 this_rtx = gen_rtx_REG (Pmode, 3);
21764 /* Apply the constant offset, if required. */
21766 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21768 /* Apply the offset from the vtable, if required. */
21771 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21772 rtx tmp = gen_rtx_REG (Pmode, 12);
21774 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21775 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21777 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21778 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21782 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21784 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21786 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21789 /* Generate a tail call to the target function. */
21790 if (!TREE_USED (function))
21792 assemble_external (function);
21793 TREE_USED (function) = 1;
21795 funexp = XEXP (DECL_RTL (function), 0);
21796 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21799 if (MACHOPIC_INDIRECT)
21800 funexp = machopic_indirect_call_target (funexp);
21803 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21804 generate sibcall RTL explicitly. */
21805 insn = emit_call_insn (
21806 gen_rtx_PARALLEL (VOIDmode,
21808 gen_rtx_CALL (VOIDmode,
21809 funexp, const0_rtx),
21810 gen_rtx_USE (VOIDmode, const0_rtx),
21811 gen_rtx_USE (VOIDmode,
21812 gen_rtx_REG (SImode,
21815 SIBLING_CALL_P (insn) = 1;
21818 /* Run just enough of rest_of_compilation to get the insns emitted.
21819 There's not really enough bulk here to make other passes such as
21820 instruction scheduling worth while. Note that use_thunk calls
21821 assemble_start_function and assemble_end_function. */
21822 insn = get_insns ();
21823 insn_locators_alloc ();
21824 shorten_branches (insn);
21825 final_start_function (insn, file, 1);
21826 final (insn, file, 1);
21827 final_end_function ();
21829 reload_completed = 0;
21830 epilogue_completed = 0;
21833 /* A quick summary of the various types of 'constant-pool tables'
21836 Target Flags Name One table per
21837 AIX (none) AIX TOC object file
21838 AIX -mfull-toc AIX TOC object file
21839 AIX -mminimal-toc AIX minimal TOC translation unit
21840 SVR4/EABI (none) SVR4 SDATA object file
21841 SVR4/EABI -fpic SVR4 pic object file
21842 SVR4/EABI -fPIC SVR4 PIC translation unit
21843 SVR4/EABI -mrelocatable EABI TOC function
21844 SVR4/EABI -maix AIX TOC object file
21845 SVR4/EABI -maix -mminimal-toc
21846 AIX minimal TOC translation unit
21848 Name Reg. Set by entries contains:
21849 made by addrs? fp? sum?
21851 AIX TOC 2 crt0 as Y option option
21852 AIX minimal TOC 30 prolog gcc Y Y option
21853 SVR4 SDATA 13 crt0 gcc N Y N
21854 SVR4 pic 30 prolog ld Y not yet N
21855 SVR4 PIC 30 prolog gcc Y option option
21856 EABI TOC 30 prolog gcc Y option option
21860 /* Hash functions for the hash table. */
21863 rs6000_hash_constant (rtx k)
21865 enum rtx_code code = GET_CODE (k);
21866 enum machine_mode mode = GET_MODE (k);
21867 unsigned result = (code << 3) ^ mode;
21868 const char *format;
21871 format = GET_RTX_FORMAT (code);
21872 flen = strlen (format);
21878 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21881 if (mode != VOIDmode)
21882 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21894 for (; fidx < flen; fidx++)
21895 switch (format[fidx])
21900 const char *str = XSTR (k, fidx);
21901 len = strlen (str);
21902 result = result * 613 + len;
21903 for (i = 0; i < len; i++)
21904 result = result * 613 + (unsigned) str[i];
21909 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21913 result = result * 613 + (unsigned) XINT (k, fidx);
21916 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21917 result = result * 613 + (unsigned) XWINT (k, fidx);
21921 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21922 result = result * 613 + (unsigned) (XWINT (k, fidx)
21929 gcc_unreachable ();
21936 toc_hash_function (const void *hash_entry)
21938 const struct toc_hash_struct *thc =
21939 (const struct toc_hash_struct *) hash_entry;
21940 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21943 /* Compare H1 and H2 for equivalence. */
21946 toc_hash_eq (const void *h1, const void *h2)
21948 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21949 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21951 if (((const struct toc_hash_struct *) h1)->key_mode
21952 != ((const struct toc_hash_struct *) h2)->key_mode)
21955 return rtx_equal_p (r1, r2);
21958 /* These are the names given by the C++ front-end to vtables, and
21959 vtable-like objects. Ideally, this logic should not be here;
21960 instead, there should be some programmatic way of inquiring as
21961 to whether or not an object is a vtable. */
21963 #define VTABLE_NAME_P(NAME) \
21964 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21965 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21966 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21967 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21968 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21970 #ifdef NO_DOLLAR_IN_LABEL
21971 /* Return a GGC-allocated character string translating dollar signs in
21972 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21975 rs6000_xcoff_strip_dollar (const char *name)
21980 p = strchr (name, '$');
21982 if (p == 0 || p == name)
21985 len = strlen (name);
21986 strip = (char *) alloca (len + 1);
21987 strcpy (strip, name);
21988 p = strchr (strip, '$');
21992 p = strchr (p + 1, '$');
21995 return ggc_alloc_string (strip, len);
22000 rs6000_output_symbol_ref (FILE *file, rtx x)
22002 /* Currently C++ toc references to vtables can be emitted before it
22003 is decided whether the vtable is public or private. If this is
22004 the case, then the linker will eventually complain that there is
22005 a reference to an unknown section. Thus, for vtables only,
22006 we emit the TOC reference to reference the symbol and not the
22008 const char *name = XSTR (x, 0);
22010 if (VTABLE_NAME_P (name))
22012 RS6000_OUTPUT_BASENAME (file, name);
22015 assemble_name (file, name);
22018 /* Output a TOC entry. We derive the entry name from what is being
22022 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22025 const char *name = buf;
22027 HOST_WIDE_INT offset = 0;
22029 gcc_assert (!TARGET_NO_TOC);
22031 /* When the linker won't eliminate them, don't output duplicate
22032 TOC entries (this happens on AIX if there is any kind of TOC,
22033 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22035 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22037 struct toc_hash_struct *h;
22040 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22041 time because GGC is not initialized at that point. */
22042 if (toc_hash_table == NULL)
22043 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22044 toc_hash_eq, NULL);
22046 h = ggc_alloc_toc_hash_struct ();
22048 h->key_mode = mode;
22049 h->labelno = labelno;
22051 found = htab_find_slot (toc_hash_table, h, INSERT);
22052 if (*found == NULL)
22054 else /* This is indeed a duplicate.
22055 Set this label equal to that label. */
22057 fputs ("\t.set ", file);
22058 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22059 fprintf (file, "%d,", labelno);
22060 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22061 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22067 /* If we're going to put a double constant in the TOC, make sure it's
22068 aligned properly when strict alignment is on. */
22069 if (GET_CODE (x) == CONST_DOUBLE
22070 && STRICT_ALIGNMENT
22071 && GET_MODE_BITSIZE (mode) >= 64
22072 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22073 ASM_OUTPUT_ALIGN (file, 3);
22076 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22078 /* Handle FP constants specially. Note that if we have a minimal
22079 TOC, things we put here aren't actually in the TOC, so we can allow
22081 if (GET_CODE (x) == CONST_DOUBLE &&
22082 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22084 REAL_VALUE_TYPE rv;
22087 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22088 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22089 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22091 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22095 if (TARGET_MINIMAL_TOC)
22096 fputs (DOUBLE_INT_ASM_OP, file);
22098 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22099 k[0] & 0xffffffff, k[1] & 0xffffffff,
22100 k[2] & 0xffffffff, k[3] & 0xffffffff);
22101 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22102 k[0] & 0xffffffff, k[1] & 0xffffffff,
22103 k[2] & 0xffffffff, k[3] & 0xffffffff);
22108 if (TARGET_MINIMAL_TOC)
22109 fputs ("\t.long ", file);
22111 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22112 k[0] & 0xffffffff, k[1] & 0xffffffff,
22113 k[2] & 0xffffffff, k[3] & 0xffffffff);
22114 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22115 k[0] & 0xffffffff, k[1] & 0xffffffff,
22116 k[2] & 0xffffffff, k[3] & 0xffffffff);
22120 else if (GET_CODE (x) == CONST_DOUBLE &&
22121 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22123 REAL_VALUE_TYPE rv;
22126 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22128 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22129 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22131 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22135 if (TARGET_MINIMAL_TOC)
22136 fputs (DOUBLE_INT_ASM_OP, file);
22138 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22139 k[0] & 0xffffffff, k[1] & 0xffffffff);
22140 fprintf (file, "0x%lx%08lx\n",
22141 k[0] & 0xffffffff, k[1] & 0xffffffff);
22146 if (TARGET_MINIMAL_TOC)
22147 fputs ("\t.long ", file);
22149 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22150 k[0] & 0xffffffff, k[1] & 0xffffffff);
22151 fprintf (file, "0x%lx,0x%lx\n",
22152 k[0] & 0xffffffff, k[1] & 0xffffffff);
22156 else if (GET_CODE (x) == CONST_DOUBLE &&
22157 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22159 REAL_VALUE_TYPE rv;
22162 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22163 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22164 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22166 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22170 if (TARGET_MINIMAL_TOC)
22171 fputs (DOUBLE_INT_ASM_OP, file);
22173 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22174 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22179 if (TARGET_MINIMAL_TOC)
22180 fputs ("\t.long ", file);
22182 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22183 fprintf (file, "0x%lx\n", l & 0xffffffff);
22187 else if (GET_MODE (x) == VOIDmode
22188 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22190 unsigned HOST_WIDE_INT low;
22191 HOST_WIDE_INT high;
22193 if (GET_CODE (x) == CONST_DOUBLE)
22195 low = CONST_DOUBLE_LOW (x);
22196 high = CONST_DOUBLE_HIGH (x);
22199 #if HOST_BITS_PER_WIDE_INT == 32
22202 high = (low & 0x80000000) ? ~0 : 0;
22206 low = INTVAL (x) & 0xffffffff;
22207 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22211 /* TOC entries are always Pmode-sized, but since this
22212 is a bigendian machine then if we're putting smaller
22213 integer constants in the TOC we have to pad them.
22214 (This is still a win over putting the constants in
22215 a separate constant pool, because then we'd have
22216 to have both a TOC entry _and_ the actual constant.)
22218 For a 32-bit target, CONST_INT values are loaded and shifted
22219 entirely within `low' and can be stored in one TOC entry. */
22221 /* It would be easy to make this work, but it doesn't now. */
22222 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22224 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22226 #if HOST_BITS_PER_WIDE_INT == 32
22227 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22228 POINTER_SIZE, &low, &high, 0);
22231 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22232 high = (HOST_WIDE_INT) low >> 32;
22239 if (TARGET_MINIMAL_TOC)
22240 fputs (DOUBLE_INT_ASM_OP, file);
22242 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22243 (long) high & 0xffffffff, (long) low & 0xffffffff);
22244 fprintf (file, "0x%lx%08lx\n",
22245 (long) high & 0xffffffff, (long) low & 0xffffffff);
22250 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22252 if (TARGET_MINIMAL_TOC)
22253 fputs ("\t.long ", file);
22255 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22256 (long) high & 0xffffffff, (long) low & 0xffffffff);
22257 fprintf (file, "0x%lx,0x%lx\n",
22258 (long) high & 0xffffffff, (long) low & 0xffffffff);
22262 if (TARGET_MINIMAL_TOC)
22263 fputs ("\t.long ", file);
22265 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22266 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22272 if (GET_CODE (x) == CONST)
22274 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22275 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22277 base = XEXP (XEXP (x, 0), 0);
22278 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22281 switch (GET_CODE (base))
22284 name = XSTR (base, 0);
22288 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22289 CODE_LABEL_NUMBER (XEXP (base, 0)));
22293 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22297 gcc_unreachable ();
22300 if (TARGET_MINIMAL_TOC)
22301 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22304 fputs ("\t.tc ", file);
22305 RS6000_OUTPUT_BASENAME (file, name);
22308 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22310 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22312 fputs ("[TC],", file);
22315 /* Currently C++ toc references to vtables can be emitted before it
22316 is decided whether the vtable is public or private. If this is
22317 the case, then the linker will eventually complain that there is
22318 a TOC reference to an unknown section. Thus, for vtables only,
22319 we emit the TOC reference to reference the symbol and not the
22321 if (VTABLE_NAME_P (name))
22323 RS6000_OUTPUT_BASENAME (file, name);
22325 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22326 else if (offset > 0)
22327 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22330 output_addr_const (file, x);
22334 /* Output an assembler pseudo-op to write an ASCII string of N characters
22335 starting at P to FILE.
22337 On the RS/6000, we have to do this using the .byte operation and
22338 write out special characters outside the quoted string.
22339 Also, the assembler is broken; very long strings are truncated,
22340 so we must artificially break them up early. */
22343 output_ascii (FILE *file, const char *p, int n)
22346 int i, count_string;
22347 const char *for_string = "\t.byte \"";
22348 const char *for_decimal = "\t.byte ";
22349 const char *to_close = NULL;
22352 for (i = 0; i < n; i++)
22355 if (c >= ' ' && c < 0177)
22358 fputs (for_string, file);
22361 /* Write two quotes to get one. */
22369 for_decimal = "\"\n\t.byte ";
22373 if (count_string >= 512)
22375 fputs (to_close, file);
22377 for_string = "\t.byte \"";
22378 for_decimal = "\t.byte ";
22386 fputs (for_decimal, file);
22387 fprintf (file, "%d", c);
22389 for_string = "\n\t.byte \"";
22390 for_decimal = ", ";
22396 /* Now close the string if we have written one. Then end the line. */
22398 fputs (to_close, file);
22401 /* Generate a unique section name for FILENAME for a section type
22402 represented by SECTION_DESC. Output goes into BUF.
22404 SECTION_DESC can be any string, as long as it is different for each
22405 possible section type.
22407 We name the section in the same manner as xlc. The name begins with an
22408 underscore followed by the filename (after stripping any leading directory
22409 names) with the last period replaced by the string SECTION_DESC. If
22410 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22414 rs6000_gen_section_name (char **buf, const char *filename,
22415 const char *section_desc)
22417 const char *q, *after_last_slash, *last_period = 0;
22421 after_last_slash = filename;
22422 for (q = filename; *q; q++)
22425 after_last_slash = q + 1;
22426 else if (*q == '.')
22430 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22431 *buf = (char *) xmalloc (len);
22436 for (q = after_last_slash; *q; q++)
22438 if (q == last_period)
22440 strcpy (p, section_desc);
22441 p += strlen (section_desc);
22445 else if (ISALNUM (*q))
22449 if (last_period == 0)
22450 strcpy (p, section_desc);
22455 /* Emit profile function. */
22458 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22460 /* Non-standard profiling for kernels, which just saves LR then calls
22461 _mcount without worrying about arg saves. The idea is to change
22462 the function prologue as little as possible as it isn't easy to
22463 account for arg save/restore code added just for _mcount. */
22464 if (TARGET_PROFILE_KERNEL)
22467 if (DEFAULT_ABI == ABI_AIX)
22469 #ifndef NO_PROFILE_COUNTERS
22470 # define NO_PROFILE_COUNTERS 0
22472 if (NO_PROFILE_COUNTERS)
22473 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22474 LCT_NORMAL, VOIDmode, 0);
22478 const char *label_name;
22481 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22482 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22483 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22485 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22486 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22489 else if (DEFAULT_ABI == ABI_DARWIN)
22491 const char *mcount_name = RS6000_MCOUNT;
22492 int caller_addr_regno = LR_REGNO;
22494 /* Be conservative and always set this, at least for now. */
22495 crtl->uses_pic_offset_table = 1;
22498 /* For PIC code, set up a stub and collect the caller's address
22499 from r0, which is where the prologue puts it. */
22500 if (MACHOPIC_INDIRECT
22501 && crtl->uses_pic_offset_table)
22502 caller_addr_regno = 0;
22504 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22505 LCT_NORMAL, VOIDmode, 1,
22506 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22510 /* Write function profiler code. */
22513 output_function_profiler (FILE *file, int labelno)
22517 switch (DEFAULT_ABI)
22520 gcc_unreachable ();
22525 warning (0, "no profiling of 64-bit code for this ABI");
22528 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22529 fprintf (file, "\tmflr %s\n", reg_names[0]);
22530 if (NO_PROFILE_COUNTERS)
22532 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22533 reg_names[0], reg_names[1]);
22535 else if (TARGET_SECURE_PLT && flag_pic)
22537 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22538 reg_names[0], reg_names[1]);
22539 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22540 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22541 reg_names[12], reg_names[12]);
22542 assemble_name (file, buf);
22543 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22544 assemble_name (file, buf);
22545 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22547 else if (flag_pic == 1)
22549 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22550 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22551 reg_names[0], reg_names[1]);
22552 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22553 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22554 assemble_name (file, buf);
22555 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22557 else if (flag_pic > 1)
22559 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22560 reg_names[0], reg_names[1]);
22561 /* Now, we need to get the address of the label. */
22562 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22563 assemble_name (file, buf);
22564 fputs ("-.\n1:", file);
22565 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22566 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22567 reg_names[0], reg_names[11]);
22568 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22569 reg_names[0], reg_names[0], reg_names[11]);
22573 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22574 assemble_name (file, buf);
22575 fputs ("@ha\n", file);
22576 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22577 reg_names[0], reg_names[1]);
22578 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22579 assemble_name (file, buf);
22580 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22583 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22584 fprintf (file, "\tbl %s%s\n",
22585 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22590 if (!TARGET_PROFILE_KERNEL)
22592 /* Don't do anything, done in output_profile_hook (). */
22596 gcc_assert (!TARGET_32BIT);
22598 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22599 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22601 if (cfun->static_chain_decl != NULL)
22603 asm_fprintf (file, "\tstd %s,24(%s)\n",
22604 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22605 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22606 asm_fprintf (file, "\tld %s,24(%s)\n",
22607 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22610 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22618 /* The following variable value is the last issued insn. */
22620 static rtx last_scheduled_insn;
22622 /* The following variable helps to balance issuing of load and
22623 store instructions */
22625 static int load_store_pendulum;
22627 /* Power4 load update and store update instructions are cracked into a
22628 load or store and an integer insn which are executed in the same cycle.
22629 Branches have their own dispatch slot which does not count against the
22630 GCC issue rate, but it changes the program flow so there are no other
22631 instructions to issue in this cycle. */
22634 rs6000_variable_issue_1 (rtx insn, int more)
22636 last_scheduled_insn = insn;
22637 if (GET_CODE (PATTERN (insn)) == USE
22638 || GET_CODE (PATTERN (insn)) == CLOBBER)
22640 cached_can_issue_more = more;
22641 return cached_can_issue_more;
22644 if (insn_terminates_group_p (insn, current_group))
22646 cached_can_issue_more = 0;
22647 return cached_can_issue_more;
22650 /* If no reservation, but reach here */
22651 if (recog_memoized (insn) < 0)
22654 if (rs6000_sched_groups)
22656 if (is_microcoded_insn (insn))
22657 cached_can_issue_more = 0;
22658 else if (is_cracked_insn (insn))
22659 cached_can_issue_more = more > 2 ? more - 2 : 0;
22661 cached_can_issue_more = more - 1;
22663 return cached_can_issue_more;
22666 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22669 cached_can_issue_more = more - 1;
22670 return cached_can_issue_more;
22674 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22676 int r = rs6000_variable_issue_1 (insn, more);
22678 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22682 /* Adjust the cost of a scheduling dependency. Return the new cost of
22683 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22686 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22688 enum attr_type attr_type;
22690 if (! recog_memoized (insn))
22693 switch (REG_NOTE_KIND (link))
22697 /* Data dependency; DEP_INSN writes a register that INSN reads
22698 some cycles later. */
22700 /* Separate a load from a narrower, dependent store. */
22701 if (rs6000_sched_groups
22702 && GET_CODE (PATTERN (insn)) == SET
22703 && GET_CODE (PATTERN (dep_insn)) == SET
22704 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22705 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22706 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22707 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22710 attr_type = get_attr_type (insn);
22715 /* Tell the first scheduling pass about the latency between
22716 a mtctr and bctr (and mtlr and br/blr). The first
22717 scheduling pass will not know about this latency since
22718 the mtctr instruction, which has the latency associated
22719 to it, will be generated by reload. */
22720 return TARGET_POWER ? 5 : 4;
22722 /* Leave some extra cycles between a compare and its
22723 dependent branch, to inhibit expensive mispredicts. */
22724 if ((rs6000_cpu_attr == CPU_PPC603
22725 || rs6000_cpu_attr == CPU_PPC604
22726 || rs6000_cpu_attr == CPU_PPC604E
22727 || rs6000_cpu_attr == CPU_PPC620
22728 || rs6000_cpu_attr == CPU_PPC630
22729 || rs6000_cpu_attr == CPU_PPC750
22730 || rs6000_cpu_attr == CPU_PPC7400
22731 || rs6000_cpu_attr == CPU_PPC7450
22732 || rs6000_cpu_attr == CPU_POWER4
22733 || rs6000_cpu_attr == CPU_POWER5
22734 || rs6000_cpu_attr == CPU_POWER7
22735 || rs6000_cpu_attr == CPU_CELL)
22736 && recog_memoized (dep_insn)
22737 && (INSN_CODE (dep_insn) >= 0))
22739 switch (get_attr_type (dep_insn))
22743 case TYPE_DELAYED_COMPARE:
22744 case TYPE_IMUL_COMPARE:
22745 case TYPE_LMUL_COMPARE:
22746 case TYPE_FPCOMPARE:
22747 case TYPE_CR_LOGICAL:
22748 case TYPE_DELAYED_CR:
22757 case TYPE_STORE_UX:
22759 case TYPE_FPSTORE_U:
22760 case TYPE_FPSTORE_UX:
22761 if ((rs6000_cpu == PROCESSOR_POWER6)
22762 && recog_memoized (dep_insn)
22763 && (INSN_CODE (dep_insn) >= 0))
22766 if (GET_CODE (PATTERN (insn)) != SET)
22767 /* If this happens, we have to extend this to schedule
22768 optimally. Return default for now. */
22771 /* Adjust the cost for the case where the value written
22772 by a fixed point operation is used as the address
22773 gen value on a store. */
22774 switch (get_attr_type (dep_insn))
22781 if (! store_data_bypass_p (dep_insn, insn))
22785 case TYPE_LOAD_EXT:
22786 case TYPE_LOAD_EXT_U:
22787 case TYPE_LOAD_EXT_UX:
22788 case TYPE_VAR_SHIFT_ROTATE:
22789 case TYPE_VAR_DELAYED_COMPARE:
22791 if (! store_data_bypass_p (dep_insn, insn))
22797 case TYPE_FAST_COMPARE:
22800 case TYPE_INSERT_WORD:
22801 case TYPE_INSERT_DWORD:
22802 case TYPE_FPLOAD_U:
22803 case TYPE_FPLOAD_UX:
22805 case TYPE_STORE_UX:
22806 case TYPE_FPSTORE_U:
22807 case TYPE_FPSTORE_UX:
22809 if (! store_data_bypass_p (dep_insn, insn))
22817 case TYPE_IMUL_COMPARE:
22818 case TYPE_LMUL_COMPARE:
22820 if (! store_data_bypass_p (dep_insn, insn))
22826 if (! store_data_bypass_p (dep_insn, insn))
22832 if (! store_data_bypass_p (dep_insn, insn))
22845 case TYPE_LOAD_EXT:
22846 case TYPE_LOAD_EXT_U:
22847 case TYPE_LOAD_EXT_UX:
22848 if ((rs6000_cpu == PROCESSOR_POWER6)
22849 && recog_memoized (dep_insn)
22850 && (INSN_CODE (dep_insn) >= 0))
22853 /* Adjust the cost for the case where the value written
22854 by a fixed point instruction is used within the address
22855 gen portion of a subsequent load(u)(x) */
22856 switch (get_attr_type (dep_insn))
22863 if (set_to_load_agen (dep_insn, insn))
22867 case TYPE_LOAD_EXT:
22868 case TYPE_LOAD_EXT_U:
22869 case TYPE_LOAD_EXT_UX:
22870 case TYPE_VAR_SHIFT_ROTATE:
22871 case TYPE_VAR_DELAYED_COMPARE:
22873 if (set_to_load_agen (dep_insn, insn))
22879 case TYPE_FAST_COMPARE:
22882 case TYPE_INSERT_WORD:
22883 case TYPE_INSERT_DWORD:
22884 case TYPE_FPLOAD_U:
22885 case TYPE_FPLOAD_UX:
22887 case TYPE_STORE_UX:
22888 case TYPE_FPSTORE_U:
22889 case TYPE_FPSTORE_UX:
22891 if (set_to_load_agen (dep_insn, insn))
22899 case TYPE_IMUL_COMPARE:
22900 case TYPE_LMUL_COMPARE:
22902 if (set_to_load_agen (dep_insn, insn))
22908 if (set_to_load_agen (dep_insn, insn))
22914 if (set_to_load_agen (dep_insn, insn))
22925 if ((rs6000_cpu == PROCESSOR_POWER6)
22926 && recog_memoized (dep_insn)
22927 && (INSN_CODE (dep_insn) >= 0)
22928 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22935 /* Fall out to return default cost. */
22939 case REG_DEP_OUTPUT:
22940 /* Output dependency; DEP_INSN writes a register that INSN writes some
22942 if ((rs6000_cpu == PROCESSOR_POWER6)
22943 && recog_memoized (dep_insn)
22944 && (INSN_CODE (dep_insn) >= 0))
22946 attr_type = get_attr_type (insn);
22951 if (get_attr_type (dep_insn) == TYPE_FP)
22955 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22963 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22968 gcc_unreachable ();
22974 /* Debug version of rs6000_adjust_cost. */
22977 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22979 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22985 switch (REG_NOTE_KIND (link))
22987 default: dep = "unknown depencency"; break;
22988 case REG_DEP_TRUE: dep = "data dependency"; break;
22989 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22990 case REG_DEP_ANTI: dep = "anti depencency"; break;
22994 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22995 "%s, insn:\n", ret, cost, dep);
23003 /* The function returns a true if INSN is microcoded.
23004 Return false otherwise. */
23007 is_microcoded_insn (rtx insn)
23009 if (!insn || !NONDEBUG_INSN_P (insn)
23010 || GET_CODE (PATTERN (insn)) == USE
23011 || GET_CODE (PATTERN (insn)) == CLOBBER)
23014 if (rs6000_cpu_attr == CPU_CELL)
23015 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23017 if (rs6000_sched_groups)
23019 enum attr_type type = get_attr_type (insn);
23020 if (type == TYPE_LOAD_EXT_U
23021 || type == TYPE_LOAD_EXT_UX
23022 || type == TYPE_LOAD_UX
23023 || type == TYPE_STORE_UX
23024 || type == TYPE_MFCR)
23031 /* The function returns true if INSN is cracked into 2 instructions
23032 by the processor (and therefore occupies 2 issue slots). */
23035 is_cracked_insn (rtx insn)
23037 if (!insn || !NONDEBUG_INSN_P (insn)
23038 || GET_CODE (PATTERN (insn)) == USE
23039 || GET_CODE (PATTERN (insn)) == CLOBBER)
23042 if (rs6000_sched_groups)
23044 enum attr_type type = get_attr_type (insn);
23045 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23046 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23047 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23048 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23049 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23050 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23051 || type == TYPE_IDIV || type == TYPE_LDIV
23052 || type == TYPE_INSERT_WORD)
23059 /* The function returns true if INSN can be issued only from
23060 the branch slot. */
23063 is_branch_slot_insn (rtx insn)
23065 if (!insn || !NONDEBUG_INSN_P (insn)
23066 || GET_CODE (PATTERN (insn)) == USE
23067 || GET_CODE (PATTERN (insn)) == CLOBBER)
23070 if (rs6000_sched_groups)
23072 enum attr_type type = get_attr_type (insn);
23073 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23081 /* The function returns true if out_inst sets a value that is
23082 used in the address generation computation of in_insn */
23084 set_to_load_agen (rtx out_insn, rtx in_insn)
23086 rtx out_set, in_set;
23088 /* For performance reasons, only handle the simple case where
23089 both loads are a single_set. */
23090 out_set = single_set (out_insn);
23093 in_set = single_set (in_insn);
23095 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23101 /* The function returns true if the target storage location of
23102 out_insn is adjacent to the target storage location of in_insn */
23103 /* Return 1 if memory locations are adjacent. */
23106 adjacent_mem_locations (rtx insn1, rtx insn2)
23109 rtx a = get_store_dest (PATTERN (insn1));
23110 rtx b = get_store_dest (PATTERN (insn2));
23112 if ((GET_CODE (XEXP (a, 0)) == REG
23113 || (GET_CODE (XEXP (a, 0)) == PLUS
23114 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23115 && (GET_CODE (XEXP (b, 0)) == REG
23116 || (GET_CODE (XEXP (b, 0)) == PLUS
23117 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23119 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23122 if (GET_CODE (XEXP (a, 0)) == PLUS)
23124 reg0 = XEXP (XEXP (a, 0), 0);
23125 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23128 reg0 = XEXP (a, 0);
23130 if (GET_CODE (XEXP (b, 0)) == PLUS)
23132 reg1 = XEXP (XEXP (b, 0), 0);
23133 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23136 reg1 = XEXP (b, 0);
23138 val_diff = val1 - val0;
23140 return ((REGNO (reg0) == REGNO (reg1))
23141 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23142 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23148 /* A C statement (sans semicolon) to update the integer scheduling
23149 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23150 INSN earlier, reduce the priority to execute INSN later. Do not
23151 define this macro if you do not need to adjust the scheduling
23152 priorities of insns. */
23155 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23157 /* On machines (like the 750) which have asymmetric integer units,
23158 where one integer unit can do multiply and divides and the other
23159 can't, reduce the priority of multiply/divide so it is scheduled
23160 before other integer operations. */
23163 if (! INSN_P (insn))
23166 if (GET_CODE (PATTERN (insn)) == USE)
23169 switch (rs6000_cpu_attr) {
23171 switch (get_attr_type (insn))
23178 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23179 priority, priority);
23180 if (priority >= 0 && priority < 0x01000000)
23187 if (insn_must_be_first_in_group (insn)
23188 && reload_completed
23189 && current_sched_info->sched_max_insns_priority
23190 && rs6000_sched_restricted_insns_priority)
23193 /* Prioritize insns that can be dispatched only in the first
23195 if (rs6000_sched_restricted_insns_priority == 1)
23196 /* Attach highest priority to insn. This means that in
23197 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23198 precede 'priority' (critical path) considerations. */
23199 return current_sched_info->sched_max_insns_priority;
23200 else if (rs6000_sched_restricted_insns_priority == 2)
23201 /* Increase priority of insn by a minimal amount. This means that in
23202 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23203 considerations precede dispatch-slot restriction considerations. */
23204 return (priority + 1);
23207 if (rs6000_cpu == PROCESSOR_POWER6
23208 && ((load_store_pendulum == -2 && is_load_insn (insn))
23209 || (load_store_pendulum == 2 && is_store_insn (insn))))
23210 /* Attach highest priority to insn if the scheduler has just issued two
23211 stores and this instruction is a load, or two loads and this instruction
23212 is a store. Power6 wants loads and stores scheduled alternately
23214 return current_sched_info->sched_max_insns_priority;
23219 /* Return true if the instruction is nonpipelined on the Cell. */
23221 is_nonpipeline_insn (rtx insn)
23223 enum attr_type type;
23224 if (!insn || !NONDEBUG_INSN_P (insn)
23225 || GET_CODE (PATTERN (insn)) == USE
23226 || GET_CODE (PATTERN (insn)) == CLOBBER)
23229 type = get_attr_type (insn);
23230 if (type == TYPE_IMUL
23231 || type == TYPE_IMUL2
23232 || type == TYPE_IMUL3
23233 || type == TYPE_LMUL
23234 || type == TYPE_IDIV
23235 || type == TYPE_LDIV
23236 || type == TYPE_SDIV
23237 || type == TYPE_DDIV
23238 || type == TYPE_SSQRT
23239 || type == TYPE_DSQRT
23240 || type == TYPE_MFCR
23241 || type == TYPE_MFCRF
23242 || type == TYPE_MFJMPR)
23250 /* Return how many instructions the machine can issue per cycle. */
23253 rs6000_issue_rate (void)
23255 /* Unless scheduling for register pressure, use issue rate of 1 for
23256 first scheduling pass to decrease degradation. */
23257 if (!reload_completed && !flag_sched_pressure)
23260 switch (rs6000_cpu_attr) {
23261 case CPU_RIOS1: /* ? */
23263 case CPU_PPC601: /* ? */
23272 case CPU_PPCE300C2:
23273 case CPU_PPCE300C3:
23274 case CPU_PPCE500MC:
23275 case CPU_PPCE500MC64:
23295 /* Return how many instructions to look ahead for better insn
23299 rs6000_use_sched_lookahead (void)
23301 if (rs6000_cpu_attr == CPU_PPC8540)
23303 if (rs6000_cpu_attr == CPU_CELL)
23304 return (reload_completed ? 8 : 0);
23308 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23310 rs6000_use_sched_lookahead_guard (rtx insn)
23312 if (rs6000_cpu_attr != CPU_CELL)
23315 if (insn == NULL_RTX || !INSN_P (insn))
23318 if (!reload_completed
23319 || is_nonpipeline_insn (insn)
23320 || is_microcoded_insn (insn))
23326 /* Determine is PAT refers to memory. */
23329 is_mem_ref (rtx pat)
23335 /* stack_tie does not produce any real memory traffic. */
23336 if (GET_CODE (pat) == UNSPEC
23337 && XINT (pat, 1) == UNSPEC_TIE)
23340 if (GET_CODE (pat) == MEM)
23343 /* Recursively process the pattern. */
23344 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23346 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23349 ret |= is_mem_ref (XEXP (pat, i));
23350 else if (fmt[i] == 'E')
23351 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23352 ret |= is_mem_ref (XVECEXP (pat, i, j));
23358 /* Determine if PAT is a PATTERN of a load insn. */
23361 is_load_insn1 (rtx pat)
23363 if (!pat || pat == NULL_RTX)
23366 if (GET_CODE (pat) == SET)
23367 return is_mem_ref (SET_SRC (pat));
23369 if (GET_CODE (pat) == PARALLEL)
23373 for (i = 0; i < XVECLEN (pat, 0); i++)
23374 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23381 /* Determine if INSN loads from memory. */
23384 is_load_insn (rtx insn)
23386 if (!insn || !INSN_P (insn))
23389 if (GET_CODE (insn) == CALL_INSN)
23392 return is_load_insn1 (PATTERN (insn));
23395 /* Determine if PAT is a PATTERN of a store insn. */
23398 is_store_insn1 (rtx pat)
23400 if (!pat || pat == NULL_RTX)
23403 if (GET_CODE (pat) == SET)
23404 return is_mem_ref (SET_DEST (pat));
23406 if (GET_CODE (pat) == PARALLEL)
23410 for (i = 0; i < XVECLEN (pat, 0); i++)
23411 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23418 /* Determine if INSN stores to memory. */
23421 is_store_insn (rtx insn)
23423 if (!insn || !INSN_P (insn))
23426 return is_store_insn1 (PATTERN (insn));
23429 /* Return the dest of a store insn. */
23432 get_store_dest (rtx pat)
23434 gcc_assert (is_store_insn1 (pat));
23436 if (GET_CODE (pat) == SET)
23437 return SET_DEST (pat);
23438 else if (GET_CODE (pat) == PARALLEL)
23442 for (i = 0; i < XVECLEN (pat, 0); i++)
23444 rtx inner_pat = XVECEXP (pat, 0, i);
23445 if (GET_CODE (inner_pat) == SET
23446 && is_mem_ref (SET_DEST (inner_pat)))
23450 /* We shouldn't get here, because we should have either a simple
23451 store insn or a store with update which are covered above. */
23455 /* Returns whether the dependence between INSN and NEXT is considered
23456 costly by the given target. */
23459 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23464 /* If the flag is not enabled - no dependence is considered costly;
23465 allow all dependent insns in the same group.
23466 This is the most aggressive option. */
23467 if (rs6000_sched_costly_dep == no_dep_costly)
23470 /* If the flag is set to 1 - a dependence is always considered costly;
23471 do not allow dependent instructions in the same group.
23472 This is the most conservative option. */
23473 if (rs6000_sched_costly_dep == all_deps_costly)
23476 insn = DEP_PRO (dep);
23477 next = DEP_CON (dep);
23479 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23480 && is_load_insn (next)
23481 && is_store_insn (insn))
23482 /* Prevent load after store in the same group. */
23485 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23486 && is_load_insn (next)
23487 && is_store_insn (insn)
23488 && DEP_TYPE (dep) == REG_DEP_TRUE)
23489 /* Prevent load after store in the same group if it is a true
23493 /* The flag is set to X; dependences with latency >= X are considered costly,
23494 and will not be scheduled in the same group. */
23495 if (rs6000_sched_costly_dep <= max_dep_latency
23496 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23502 /* Return the next insn after INSN that is found before TAIL is reached,
23503 skipping any "non-active" insns - insns that will not actually occupy
23504 an issue slot. Return NULL_RTX if such an insn is not found. */
23507 get_next_active_insn (rtx insn, rtx tail)
23509 if (insn == NULL_RTX || insn == tail)
23514 insn = NEXT_INSN (insn);
23515 if (insn == NULL_RTX || insn == tail)
23520 || (NONJUMP_INSN_P (insn)
23521 && GET_CODE (PATTERN (insn)) != USE
23522 && GET_CODE (PATTERN (insn)) != CLOBBER
23523 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23529 /* We are about to begin issuing insns for this clock cycle. */
23532 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23533 rtx *ready ATTRIBUTE_UNUSED,
23534 int *pn_ready ATTRIBUTE_UNUSED,
23535 int clock_var ATTRIBUTE_UNUSED)
23537 int n_ready = *pn_ready;
23540 fprintf (dump, "// rs6000_sched_reorder :\n");
23542 /* Reorder the ready list, if the second to last ready insn
23543 is a nonepipeline insn. */
23544 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23546 if (is_nonpipeline_insn (ready[n_ready - 1])
23547 && (recog_memoized (ready[n_ready - 2]) > 0))
23548 /* Simply swap first two insns. */
23550 rtx tmp = ready[n_ready - 1];
23551 ready[n_ready - 1] = ready[n_ready - 2];
23552 ready[n_ready - 2] = tmp;
23556 if (rs6000_cpu == PROCESSOR_POWER6)
23557 load_store_pendulum = 0;
23559 return rs6000_issue_rate ();
23562 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23565 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23566 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23569 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23571 /* For Power6, we need to handle some special cases to try and keep the
23572 store queue from overflowing and triggering expensive flushes.
23574 This code monitors how load and store instructions are being issued
23575 and skews the ready list one way or the other to increase the likelihood
23576 that a desired instruction is issued at the proper time.
23578 A couple of things are done. First, we maintain a "load_store_pendulum"
23579 to track the current state of load/store issue.
23581 - If the pendulum is at zero, then no loads or stores have been
23582 issued in the current cycle so we do nothing.
23584 - If the pendulum is 1, then a single load has been issued in this
23585 cycle and we attempt to locate another load in the ready list to
23588 - If the pendulum is -2, then two stores have already been
23589 issued in this cycle, so we increase the priority of the first load
23590 in the ready list to increase it's likelihood of being chosen first
23593 - If the pendulum is -1, then a single store has been issued in this
23594 cycle and we attempt to locate another store in the ready list to
23595 issue with it, preferring a store to an adjacent memory location to
23596 facilitate store pairing in the store queue.
23598 - If the pendulum is 2, then two loads have already been
23599 issued in this cycle, so we increase the priority of the first store
23600 in the ready list to increase it's likelihood of being chosen first
23603 - If the pendulum < -2 or > 2, then do nothing.
23605 Note: This code covers the most common scenarios. There exist non
23606 load/store instructions which make use of the LSU and which
23607 would need to be accounted for to strictly model the behavior
23608 of the machine. Those instructions are currently unaccounted
23609 for to help minimize compile time overhead of this code.
23611 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23617 if (is_store_insn (last_scheduled_insn))
23618 /* Issuing a store, swing the load_store_pendulum to the left */
23619 load_store_pendulum--;
23620 else if (is_load_insn (last_scheduled_insn))
23621 /* Issuing a load, swing the load_store_pendulum to the right */
23622 load_store_pendulum++;
23624 return cached_can_issue_more;
23626 /* If the pendulum is balanced, or there is only one instruction on
23627 the ready list, then all is well, so return. */
23628 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23629 return cached_can_issue_more;
23631 if (load_store_pendulum == 1)
23633 /* A load has been issued in this cycle. Scan the ready list
23634 for another load to issue with it */
23639 if (is_load_insn (ready[pos]))
23641 /* Found a load. Move it to the head of the ready list,
23642 and adjust it's priority so that it is more likely to
23645 for (i=pos; i<*pn_ready-1; i++)
23646 ready[i] = ready[i + 1];
23647 ready[*pn_ready-1] = tmp;
23649 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23650 INSN_PRIORITY (tmp)++;
23656 else if (load_store_pendulum == -2)
23658 /* Two stores have been issued in this cycle. Increase the
23659 priority of the first load in the ready list to favor it for
23660 issuing in the next cycle. */
23665 if (is_load_insn (ready[pos])
23667 && INSN_PRIORITY_KNOWN (ready[pos]))
23669 INSN_PRIORITY (ready[pos])++;
23671 /* Adjust the pendulum to account for the fact that a load
23672 was found and increased in priority. This is to prevent
23673 increasing the priority of multiple loads */
23674 load_store_pendulum--;
23681 else if (load_store_pendulum == -1)
23683 /* A store has been issued in this cycle. Scan the ready list for
23684 another store to issue with it, preferring a store to an adjacent
23686 int first_store_pos = -1;
23692 if (is_store_insn (ready[pos]))
23694 /* Maintain the index of the first store found on the
23696 if (first_store_pos == -1)
23697 first_store_pos = pos;
23699 if (is_store_insn (last_scheduled_insn)
23700 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23702 /* Found an adjacent store. Move it to the head of the
23703 ready list, and adjust it's priority so that it is
23704 more likely to stay there */
23706 for (i=pos; i<*pn_ready-1; i++)
23707 ready[i] = ready[i + 1];
23708 ready[*pn_ready-1] = tmp;
23710 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23711 INSN_PRIORITY (tmp)++;
23713 first_store_pos = -1;
23721 if (first_store_pos >= 0)
23723 /* An adjacent store wasn't found, but a non-adjacent store was,
23724 so move the non-adjacent store to the front of the ready
23725 list, and adjust its priority so that it is more likely to
23727 tmp = ready[first_store_pos];
23728 for (i=first_store_pos; i<*pn_ready-1; i++)
23729 ready[i] = ready[i + 1];
23730 ready[*pn_ready-1] = tmp;
23731 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23732 INSN_PRIORITY (tmp)++;
23735 else if (load_store_pendulum == 2)
23737 /* Two loads have been issued in this cycle. Increase the priority
23738 of the first store in the ready list to favor it for issuing in
23744 if (is_store_insn (ready[pos])
23746 && INSN_PRIORITY_KNOWN (ready[pos]))
23748 INSN_PRIORITY (ready[pos])++;
23750 /* Adjust the pendulum to account for the fact that a store
23751 was found and increased in priority. This is to prevent
23752 increasing the priority of multiple stores */
23753 load_store_pendulum++;
23762 return cached_can_issue_more;
23765 /* Return whether the presence of INSN causes a dispatch group termination
23766 of group WHICH_GROUP.
23768 If WHICH_GROUP == current_group, this function will return true if INSN
23769 causes the termination of the current group (i.e, the dispatch group to
23770 which INSN belongs). This means that INSN will be the last insn in the
23771 group it belongs to.
23773 If WHICH_GROUP == previous_group, this function will return true if INSN
23774 causes the termination of the previous group (i.e, the dispatch group that
23775 precedes the group to which INSN belongs). This means that INSN will be
23776 the first insn in the group it belongs to). */
23779 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23786 first = insn_must_be_first_in_group (insn);
23787 last = insn_must_be_last_in_group (insn);
23792 if (which_group == current_group)
23794 else if (which_group == previous_group)
23802 insn_must_be_first_in_group (rtx insn)
23804 enum attr_type type;
23807 || GET_CODE (insn) == NOTE
23808 || DEBUG_INSN_P (insn)
23809 || GET_CODE (PATTERN (insn)) == USE
23810 || GET_CODE (PATTERN (insn)) == CLOBBER)
23813 switch (rs6000_cpu)
23815 case PROCESSOR_POWER5:
23816 if (is_cracked_insn (insn))
23818 case PROCESSOR_POWER4:
23819 if (is_microcoded_insn (insn))
23822 if (!rs6000_sched_groups)
23825 type = get_attr_type (insn);
23832 case TYPE_DELAYED_CR:
23833 case TYPE_CR_LOGICAL:
23847 case PROCESSOR_POWER6:
23848 type = get_attr_type (insn);
23852 case TYPE_INSERT_DWORD:
23856 case TYPE_VAR_SHIFT_ROTATE:
23863 case TYPE_INSERT_WORD:
23864 case TYPE_DELAYED_COMPARE:
23865 case TYPE_IMUL_COMPARE:
23866 case TYPE_LMUL_COMPARE:
23867 case TYPE_FPCOMPARE:
23878 case TYPE_LOAD_EXT_UX:
23880 case TYPE_STORE_UX:
23881 case TYPE_FPLOAD_U:
23882 case TYPE_FPLOAD_UX:
23883 case TYPE_FPSTORE_U:
23884 case TYPE_FPSTORE_UX:
23890 case PROCESSOR_POWER7:
23891 type = get_attr_type (insn);
23895 case TYPE_CR_LOGICAL:
23902 case TYPE_DELAYED_COMPARE:
23903 case TYPE_VAR_DELAYED_COMPARE:
23909 case TYPE_LOAD_EXT:
23910 case TYPE_LOAD_EXT_U:
23911 case TYPE_LOAD_EXT_UX:
23913 case TYPE_STORE_UX:
23914 case TYPE_FPLOAD_U:
23915 case TYPE_FPLOAD_UX:
23916 case TYPE_FPSTORE_U:
23917 case TYPE_FPSTORE_UX:
23933 insn_must_be_last_in_group (rtx insn)
23935 enum attr_type type;
23938 || GET_CODE (insn) == NOTE
23939 || DEBUG_INSN_P (insn)
23940 || GET_CODE (PATTERN (insn)) == USE
23941 || GET_CODE (PATTERN (insn)) == CLOBBER)
23944 switch (rs6000_cpu) {
23945 case PROCESSOR_POWER4:
23946 case PROCESSOR_POWER5:
23947 if (is_microcoded_insn (insn))
23950 if (is_branch_slot_insn (insn))
23954 case PROCESSOR_POWER6:
23955 type = get_attr_type (insn);
23962 case TYPE_VAR_SHIFT_ROTATE:
23969 case TYPE_DELAYED_COMPARE:
23970 case TYPE_IMUL_COMPARE:
23971 case TYPE_LMUL_COMPARE:
23972 case TYPE_FPCOMPARE:
23986 case PROCESSOR_POWER7:
23987 type = get_attr_type (insn);
23995 case TYPE_LOAD_EXT_U:
23996 case TYPE_LOAD_EXT_UX:
23997 case TYPE_STORE_UX:
24010 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24011 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24014 is_costly_group (rtx *group_insns, rtx next_insn)
24017 int issue_rate = rs6000_issue_rate ();
24019 for (i = 0; i < issue_rate; i++)
24021 sd_iterator_def sd_it;
24023 rtx insn = group_insns[i];
24028 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24030 rtx next = DEP_CON (dep);
24032 if (next == next_insn
24033 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24041 /* Utility of the function redefine_groups.
24042 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24043 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24044 to keep it "far" (in a separate group) from GROUP_INSNS, following
24045 one of the following schemes, depending on the value of the flag
24046 -minsert_sched_nops = X:
24047 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24048 in order to force NEXT_INSN into a separate group.
24049 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24050 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24051 insertion (has a group just ended, how many vacant issue slots remain in the
24052 last group, and how many dispatch groups were encountered so far). */
24055 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24056 rtx next_insn, bool *group_end, int can_issue_more,
24061 int issue_rate = rs6000_issue_rate ();
24062 bool end = *group_end;
24065 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24066 return can_issue_more;
24068 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24069 return can_issue_more;
24071 force = is_costly_group (group_insns, next_insn);
24073 return can_issue_more;
24075 if (sched_verbose > 6)
24076 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24077 *group_count ,can_issue_more);
24079 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24082 can_issue_more = 0;
24084 /* Since only a branch can be issued in the last issue_slot, it is
24085 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24086 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24087 in this case the last nop will start a new group and the branch
24088 will be forced to the new group. */
24089 if (can_issue_more && !is_branch_slot_insn (next_insn))
24092 while (can_issue_more > 0)
24095 emit_insn_before (nop, next_insn);
24103 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24105 int n_nops = rs6000_sched_insert_nops;
24107 /* Nops can't be issued from the branch slot, so the effective
24108 issue_rate for nops is 'issue_rate - 1'. */
24109 if (can_issue_more == 0)
24110 can_issue_more = issue_rate;
24112 if (can_issue_more == 0)
24114 can_issue_more = issue_rate - 1;
24117 for (i = 0; i < issue_rate; i++)
24119 group_insns[i] = 0;
24126 emit_insn_before (nop, next_insn);
24127 if (can_issue_more == issue_rate - 1) /* new group begins */
24130 if (can_issue_more == 0)
24132 can_issue_more = issue_rate - 1;
24135 for (i = 0; i < issue_rate; i++)
24137 group_insns[i] = 0;
24143 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24146 /* Is next_insn going to start a new group? */
24149 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24150 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24151 || (can_issue_more < issue_rate &&
24152 insn_terminates_group_p (next_insn, previous_group)));
24153 if (*group_end && end)
24156 if (sched_verbose > 6)
24157 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24158 *group_count, can_issue_more);
24159 return can_issue_more;
24162 return can_issue_more;
24165 /* This function tries to synch the dispatch groups that the compiler "sees"
24166 with the dispatch groups that the processor dispatcher is expected to
24167 form in practice. It tries to achieve this synchronization by forcing the
24168 estimated processor grouping on the compiler (as opposed to the function
24169 'pad_goups' which tries to force the scheduler's grouping on the processor).
24171 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24172 examines the (estimated) dispatch groups that will be formed by the processor
24173 dispatcher. It marks these group boundaries to reflect the estimated
24174 processor grouping, overriding the grouping that the scheduler had marked.
24175 Depending on the value of the flag '-minsert-sched-nops' this function can
24176 force certain insns into separate groups or force a certain distance between
24177 them by inserting nops, for example, if there exists a "costly dependence"
24180 The function estimates the group boundaries that the processor will form as
24181 follows: It keeps track of how many vacant issue slots are available after
24182 each insn. A subsequent insn will start a new group if one of the following
24184 - no more vacant issue slots remain in the current dispatch group.
24185 - only the last issue slot, which is the branch slot, is vacant, but the next
24186 insn is not a branch.
24187 - only the last 2 or less issue slots, including the branch slot, are vacant,
24188 which means that a cracked insn (which occupies two issue slots) can't be
24189 issued in this group.
24190 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24191 start a new group. */
24194 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24196 rtx insn, next_insn;
24198 int can_issue_more;
24201 int group_count = 0;
24205 issue_rate = rs6000_issue_rate ();
24206 group_insns = XALLOCAVEC (rtx, issue_rate);
24207 for (i = 0; i < issue_rate; i++)
24209 group_insns[i] = 0;
24211 can_issue_more = issue_rate;
24213 insn = get_next_active_insn (prev_head_insn, tail);
24216 while (insn != NULL_RTX)
24218 slot = (issue_rate - can_issue_more);
24219 group_insns[slot] = insn;
24221 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24222 if (insn_terminates_group_p (insn, current_group))
24223 can_issue_more = 0;
24225 next_insn = get_next_active_insn (insn, tail);
24226 if (next_insn == NULL_RTX)
24227 return group_count + 1;
24229 /* Is next_insn going to start a new group? */
24231 = (can_issue_more == 0
24232 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24233 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24234 || (can_issue_more < issue_rate &&
24235 insn_terminates_group_p (next_insn, previous_group)));
24237 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24238 next_insn, &group_end, can_issue_more,
24244 can_issue_more = 0;
24245 for (i = 0; i < issue_rate; i++)
24247 group_insns[i] = 0;
24251 if (GET_MODE (next_insn) == TImode && can_issue_more)
24252 PUT_MODE (next_insn, VOIDmode);
24253 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24254 PUT_MODE (next_insn, TImode);
24257 if (can_issue_more == 0)
24258 can_issue_more = issue_rate;
24261 return group_count;
24264 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24265 dispatch group boundaries that the scheduler had marked. Pad with nops
24266 any dispatch groups which have vacant issue slots, in order to force the
24267 scheduler's grouping on the processor dispatcher. The function
24268 returns the number of dispatch groups found. */
24271 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24273 rtx insn, next_insn;
24276 int can_issue_more;
24278 int group_count = 0;
24280 /* Initialize issue_rate. */
24281 issue_rate = rs6000_issue_rate ();
24282 can_issue_more = issue_rate;
24284 insn = get_next_active_insn (prev_head_insn, tail);
24285 next_insn = get_next_active_insn (insn, tail);
24287 while (insn != NULL_RTX)
24290 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24292 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24294 if (next_insn == NULL_RTX)
24299 /* If the scheduler had marked group termination at this location
24300 (between insn and next_insn), and neither insn nor next_insn will
24301 force group termination, pad the group with nops to force group
24304 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24305 && !insn_terminates_group_p (insn, current_group)
24306 && !insn_terminates_group_p (next_insn, previous_group))
24308 if (!is_branch_slot_insn (next_insn))
24311 while (can_issue_more)
24314 emit_insn_before (nop, next_insn);
24319 can_issue_more = issue_rate;
24324 next_insn = get_next_active_insn (insn, tail);
24327 return group_count;
24330 /* We're beginning a new block. Initialize data structures as necessary. */
24333 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24334 int sched_verbose ATTRIBUTE_UNUSED,
24335 int max_ready ATTRIBUTE_UNUSED)
24337 last_scheduled_insn = NULL_RTX;
24338 load_store_pendulum = 0;
24341 /* The following function is called at the end of scheduling BB.
24342 After reload, it inserts nops at insn group bundling. */
24345 rs6000_sched_finish (FILE *dump, int sched_verbose)
24350 fprintf (dump, "=== Finishing schedule.\n");
24352 if (reload_completed && rs6000_sched_groups)
24354 /* Do not run sched_finish hook when selective scheduling enabled. */
24355 if (sel_sched_p ())
24358 if (rs6000_sched_insert_nops == sched_finish_none)
24361 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24362 n_groups = pad_groups (dump, sched_verbose,
24363 current_sched_info->prev_head,
24364 current_sched_info->next_tail);
24366 n_groups = redefine_groups (dump, sched_verbose,
24367 current_sched_info->prev_head,
24368 current_sched_info->next_tail);
24370 if (sched_verbose >= 6)
24372 fprintf (dump, "ngroups = %d\n", n_groups);
24373 print_rtl (dump, current_sched_info->prev_head);
24374 fprintf (dump, "Done finish_sched\n");
24379 struct _rs6000_sched_context
24381 short cached_can_issue_more;
24382 rtx last_scheduled_insn;
24383 int load_store_pendulum;
24386 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24387 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24389 /* Allocate store for new scheduling context. */
24391 rs6000_alloc_sched_context (void)
24393 return xmalloc (sizeof (rs6000_sched_context_def));
24396 /* If CLEAN_P is true then initializes _SC with clean data,
24397 and from the global context otherwise. */
24399 rs6000_init_sched_context (void *_sc, bool clean_p)
24401 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24405 sc->cached_can_issue_more = 0;
24406 sc->last_scheduled_insn = NULL_RTX;
24407 sc->load_store_pendulum = 0;
24411 sc->cached_can_issue_more = cached_can_issue_more;
24412 sc->last_scheduled_insn = last_scheduled_insn;
24413 sc->load_store_pendulum = load_store_pendulum;
24417 /* Sets the global scheduling context to the one pointed to by _SC. */
24419 rs6000_set_sched_context (void *_sc)
24421 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24423 gcc_assert (sc != NULL);
24425 cached_can_issue_more = sc->cached_can_issue_more;
24426 last_scheduled_insn = sc->last_scheduled_insn;
24427 load_store_pendulum = sc->load_store_pendulum;
24432 rs6000_free_sched_context (void *_sc)
24434 gcc_assert (_sc != NULL);
24440 /* Length in units of the trampoline for entering a nested function. */
24443 rs6000_trampoline_size (void)
24447 switch (DEFAULT_ABI)
24450 gcc_unreachable ();
24453 ret = (TARGET_32BIT) ? 12 : 24;
24458 ret = (TARGET_32BIT) ? 40 : 48;
24465 /* Emit RTL insns to initialize the variable parts of a trampoline.
24466 FNADDR is an RTX for the address of the function's pure code.
24467 CXT is an RTX for the static chain value for the function. */
24470 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24472 int regsize = (TARGET_32BIT) ? 4 : 8;
24473 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24474 rtx ctx_reg = force_reg (Pmode, cxt);
24475 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24477 switch (DEFAULT_ABI)
24480 gcc_unreachable ();
24482 /* Under AIX, just build the 3 word function descriptor */
24485 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24486 rtx fn_reg = gen_reg_rtx (Pmode);
24487 rtx toc_reg = gen_reg_rtx (Pmode);
24489 /* Macro to shorten the code expansions below. */
24490 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24492 m_tramp = replace_equiv_address (m_tramp, addr);
24494 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24495 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24496 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24497 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24498 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24504 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24507 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24508 LCT_NORMAL, VOIDmode, 4,
24510 GEN_INT (rs6000_trampoline_size ()), SImode,
24518 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24519 identifier as an argument, so the front end shouldn't look it up. */
24522 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24524 return is_attribute_p ("altivec", attr_id);
24527 /* Handle the "altivec" attribute. The attribute may have
24528 arguments as follows:
24530 __attribute__((altivec(vector__)))
24531 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24532 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24534 and may appear more than once (e.g., 'vector bool char') in a
24535 given declaration. */
24538 rs6000_handle_altivec_attribute (tree *node,
24539 tree name ATTRIBUTE_UNUSED,
24541 int flags ATTRIBUTE_UNUSED,
24542 bool *no_add_attrs)
24544 tree type = *node, result = NULL_TREE;
24545 enum machine_mode mode;
24548 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24549 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24550 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24553 while (POINTER_TYPE_P (type)
24554 || TREE_CODE (type) == FUNCTION_TYPE
24555 || TREE_CODE (type) == METHOD_TYPE
24556 || TREE_CODE (type) == ARRAY_TYPE)
24557 type = TREE_TYPE (type);
24559 mode = TYPE_MODE (type);
24561 /* Check for invalid AltiVec type qualifiers. */
24562 if (type == long_double_type_node)
24563 error ("use of %<long double%> in AltiVec types is invalid");
24564 else if (type == boolean_type_node)
24565 error ("use of boolean types in AltiVec types is invalid");
24566 else if (TREE_CODE (type) == COMPLEX_TYPE)
24567 error ("use of %<complex%> in AltiVec types is invalid");
24568 else if (DECIMAL_FLOAT_MODE_P (mode))
24569 error ("use of decimal floating point types in AltiVec types is invalid");
24570 else if (!TARGET_VSX)
24572 if (type == long_unsigned_type_node || type == long_integer_type_node)
24575 error ("use of %<long%> in AltiVec types is invalid for "
24576 "64-bit code without -mvsx");
24577 else if (rs6000_warn_altivec_long)
24578 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24581 else if (type == long_long_unsigned_type_node
24582 || type == long_long_integer_type_node)
24583 error ("use of %<long long%> in AltiVec types is invalid without "
24585 else if (type == double_type_node)
24586 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24589 switch (altivec_type)
24592 unsigned_p = TYPE_UNSIGNED (type);
24596 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24599 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24602 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24605 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24607 case SFmode: result = V4SF_type_node; break;
24608 case DFmode: result = V2DF_type_node; break;
24609 /* If the user says 'vector int bool', we may be handed the 'bool'
24610 attribute _before_ the 'vector' attribute, and so select the
24611 proper type in the 'b' case below. */
24612 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24613 case V2DImode: case V2DFmode:
24621 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24622 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24623 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24624 case QImode: case V16QImode: result = bool_V16QI_type_node;
24631 case V8HImode: result = pixel_V8HI_type_node;
24637 /* Propagate qualifiers attached to the element type
24638 onto the vector type. */
24639 if (result && result != type && TYPE_QUALS (type))
24640 result = build_qualified_type (result, TYPE_QUALS (type));
24642 *no_add_attrs = true; /* No need to hang on to the attribute. */
24645 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24650 /* AltiVec defines four built-in scalar types that serve as vector
24651 elements; we must teach the compiler how to mangle them. */
24653 static const char *
24654 rs6000_mangle_type (const_tree type)
24656 type = TYPE_MAIN_VARIANT (type);
24658 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24659 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24662 if (type == bool_char_type_node) return "U6__boolc";
24663 if (type == bool_short_type_node) return "U6__bools";
24664 if (type == pixel_type_node) return "u7__pixel";
24665 if (type == bool_int_type_node) return "U6__booli";
24666 if (type == bool_long_type_node) return "U6__booll";
24668 /* Mangle IBM extended float long double as `g' (__float128) on
24669 powerpc*-linux where long-double-64 previously was the default. */
24670 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24672 && TARGET_LONG_DOUBLE_128
24673 && !TARGET_IEEEQUAD)
24676 /* For all other types, use normal C++ mangling. */
24680 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24681 struct attribute_spec.handler. */
24684 rs6000_handle_longcall_attribute (tree *node, tree name,
24685 tree args ATTRIBUTE_UNUSED,
24686 int flags ATTRIBUTE_UNUSED,
24687 bool *no_add_attrs)
24689 if (TREE_CODE (*node) != FUNCTION_TYPE
24690 && TREE_CODE (*node) != FIELD_DECL
24691 && TREE_CODE (*node) != TYPE_DECL)
24693 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24695 *no_add_attrs = true;
24701 /* Set longcall attributes on all functions declared when
24702 rs6000_default_long_calls is true. */
24704 rs6000_set_default_type_attributes (tree type)
24706 if (rs6000_default_long_calls
24707 && (TREE_CODE (type) == FUNCTION_TYPE
24708 || TREE_CODE (type) == METHOD_TYPE))
24709 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24711 TYPE_ATTRIBUTES (type));
24714 darwin_set_default_type_attributes (type);
24718 /* Return a reference suitable for calling a function with the
24719 longcall attribute. */
24722 rs6000_longcall_ref (rtx call_ref)
24724 const char *call_name;
24727 if (GET_CODE (call_ref) != SYMBOL_REF)
24730 /* System V adds '.' to the internal name, so skip them. */
24731 call_name = XSTR (call_ref, 0);
24732 if (*call_name == '.')
24734 while (*call_name == '.')
24737 node = get_identifier (call_name);
24738 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24741 return force_reg (Pmode, call_ref);
24744 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24745 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24748 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24749 struct attribute_spec.handler. */
24751 rs6000_handle_struct_attribute (tree *node, tree name,
24752 tree args ATTRIBUTE_UNUSED,
24753 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24756 if (DECL_P (*node))
24758 if (TREE_CODE (*node) == TYPE_DECL)
24759 type = &TREE_TYPE (*node);
24764 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24765 || TREE_CODE (*type) == UNION_TYPE)))
24767 warning (OPT_Wattributes, "%qE attribute ignored", name);
24768 *no_add_attrs = true;
24771 else if ((is_attribute_p ("ms_struct", name)
24772 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24773 || ((is_attribute_p ("gcc_struct", name)
24774 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24776 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24778 *no_add_attrs = true;
24785 rs6000_ms_bitfield_layout_p (const_tree record_type)
24787 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24788 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24789 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24792 #ifdef USING_ELFOS_H
24794 /* A get_unnamed_section callback, used for switching to toc_section. */
24797 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24799 if (DEFAULT_ABI == ABI_AIX
24800 && TARGET_MINIMAL_TOC
24801 && !TARGET_RELOCATABLE)
24803 if (!toc_initialized)
24805 toc_initialized = 1;
24806 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24807 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24808 fprintf (asm_out_file, "\t.tc ");
24809 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24810 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24811 fprintf (asm_out_file, "\n");
24813 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24814 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24815 fprintf (asm_out_file, " = .+32768\n");
24818 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24820 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24821 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24824 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24825 if (!toc_initialized)
24827 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24828 fprintf (asm_out_file, " = .+32768\n");
24829 toc_initialized = 1;
24834 /* Implement TARGET_ASM_INIT_SECTIONS. */
24837 rs6000_elf_asm_init_sections (void)
24840 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24843 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24844 SDATA2_SECTION_ASM_OP);
24847 /* Implement TARGET_SELECT_RTX_SECTION. */
24850 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24851 unsigned HOST_WIDE_INT align)
24853 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24854 return toc_section;
24856 return default_elf_select_rtx_section (mode, x, align);
24859 /* For a SYMBOL_REF, set generic flags and then perform some
24860 target-specific processing.
24862 When the AIX ABI is requested on a non-AIX system, replace the
24863 function name with the real name (with a leading .) rather than the
24864 function descriptor name. This saves a lot of overriding code to
24865 read the prefixes. */
24868 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24870 default_encode_section_info (decl, rtl, first);
24873 && TREE_CODE (decl) == FUNCTION_DECL
24875 && DEFAULT_ABI == ABI_AIX)
24877 rtx sym_ref = XEXP (rtl, 0);
24878 size_t len = strlen (XSTR (sym_ref, 0));
24879 char *str = XALLOCAVEC (char, len + 2);
24881 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24882 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24887 compare_section_name (const char *section, const char *templ)
24891 len = strlen (templ);
24892 return (strncmp (section, templ, len) == 0
24893 && (section[len] == 0 || section[len] == '.'));
24897 rs6000_elf_in_small_data_p (const_tree decl)
24899 if (rs6000_sdata == SDATA_NONE)
24902 /* We want to merge strings, so we never consider them small data. */
24903 if (TREE_CODE (decl) == STRING_CST)
24906 /* Functions are never in the small data area. */
24907 if (TREE_CODE (decl) == FUNCTION_DECL)
24910 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24912 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24913 if (compare_section_name (section, ".sdata")
24914 || compare_section_name (section, ".sdata2")
24915 || compare_section_name (section, ".gnu.linkonce.s")
24916 || compare_section_name (section, ".sbss")
24917 || compare_section_name (section, ".sbss2")
24918 || compare_section_name (section, ".gnu.linkonce.sb")
24919 || strcmp (section, ".PPC.EMB.sdata0") == 0
24920 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24925 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24928 && size <= g_switch_value
24929 /* If it's not public, and we're not going to reference it there,
24930 there's no need to put it in the small data section. */
24931 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24938 #endif /* USING_ELFOS_H */
24940 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24943 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24945 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24948 /* Return a REG that occurs in ADDR with coefficient 1.
24949 ADDR can be effectively incremented by incrementing REG.
24951 r0 is special and we must not select it as an address
24952 register by this routine since our caller will try to
24953 increment the returned register via an "la" instruction. */
24956 find_addr_reg (rtx addr)
24958 while (GET_CODE (addr) == PLUS)
24960 if (GET_CODE (XEXP (addr, 0)) == REG
24961 && REGNO (XEXP (addr, 0)) != 0)
24962 addr = XEXP (addr, 0);
24963 else if (GET_CODE (XEXP (addr, 1)) == REG
24964 && REGNO (XEXP (addr, 1)) != 0)
24965 addr = XEXP (addr, 1);
24966 else if (CONSTANT_P (XEXP (addr, 0)))
24967 addr = XEXP (addr, 1);
24968 else if (CONSTANT_P (XEXP (addr, 1)))
24969 addr = XEXP (addr, 0);
24971 gcc_unreachable ();
24973 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24978 rs6000_fatal_bad_address (rtx op)
24980 fatal_insn ("bad address", op);
24985 typedef struct branch_island_d {
24986 tree function_name;
24991 DEF_VEC_O(branch_island);
24992 DEF_VEC_ALLOC_O(branch_island,gc);
24994 static VEC(branch_island,gc) *branch_islands;
24996 /* Remember to generate a branch island for far calls to the given
25000 add_compiler_branch_island (tree label_name, tree function_name,
25003 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25005 bi->function_name = function_name;
25006 bi->label_name = label_name;
25007 bi->line_number = line_number;
25010 /* Generate far-jump branch islands for everything recorded in
25011 branch_islands. Invoked immediately after the last instruction of
25012 the epilogue has been emitted; the branch islands must be appended
25013 to, and contiguous with, the function body. Mach-O stubs are
25014 generated in machopic_output_stub(). */
25017 macho_branch_islands (void)
25021 while (!VEC_empty (branch_island, branch_islands))
25023 branch_island *bi = VEC_last (branch_island, branch_islands);
25024 const char *label = IDENTIFIER_POINTER (bi->label_name);
25025 const char *name = IDENTIFIER_POINTER (bi->function_name);
25026 char name_buf[512];
25027 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25028 if (name[0] == '*' || name[0] == '&')
25029 strcpy (name_buf, name+1);
25033 strcpy (name_buf+1, name);
25035 strcpy (tmp_buf, "\n");
25036 strcat (tmp_buf, label);
25037 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25038 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25039 dbxout_stabd (N_SLINE, bi->line_number);
25040 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25043 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25044 strcat (tmp_buf, label);
25045 strcat (tmp_buf, "_pic\n");
25046 strcat (tmp_buf, label);
25047 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25049 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25050 strcat (tmp_buf, name_buf);
25051 strcat (tmp_buf, " - ");
25052 strcat (tmp_buf, label);
25053 strcat (tmp_buf, "_pic)\n");
25055 strcat (tmp_buf, "\tmtlr r0\n");
25057 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25058 strcat (tmp_buf, name_buf);
25059 strcat (tmp_buf, " - ");
25060 strcat (tmp_buf, label);
25061 strcat (tmp_buf, "_pic)\n");
25063 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25067 strcat (tmp_buf, ":\nlis r12,hi16(");
25068 strcat (tmp_buf, name_buf);
25069 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25070 strcat (tmp_buf, name_buf);
25071 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25073 output_asm_insn (tmp_buf, 0);
25074 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25075 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25076 dbxout_stabd (N_SLINE, bi->line_number);
25077 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25078 VEC_pop (branch_island, branch_islands);
25082 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25083 already there or not. */
25086 no_previous_def (tree function_name)
25091 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25092 if (function_name == bi->function_name)
25097 /* GET_PREV_LABEL gets the label name from the previous definition of
25101 get_prev_label (tree function_name)
25106 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25107 if (function_name == bi->function_name)
25108 return bi->label_name;
25112 /* INSN is either a function call or a millicode call. It may have an
25113 unconditional jump in its delay slot.
25115 CALL_DEST is the routine we are calling. */
25118 output_call (rtx insn, rtx *operands, int dest_operand_number,
25119 int cookie_operand_number)
25121 static char buf[256];
25122 if (darwin_emit_branch_islands
25123 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25124 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25127 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25129 if (no_previous_def (funname))
25131 rtx label_rtx = gen_label_rtx ();
25132 char *label_buf, temp_buf[256];
25133 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25134 CODE_LABEL_NUMBER (label_rtx));
25135 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25136 labelname = get_identifier (label_buf);
25137 add_compiler_branch_island (labelname, funname, insn_line (insn));
25140 labelname = get_prev_label (funname);
25142 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25143 instruction will reach 'foo', otherwise link as 'bl L42'".
25144 "L42" should be a 'branch island', that will do a far jump to
25145 'foo'. Branch islands are generated in
25146 macho_branch_islands(). */
25147 sprintf (buf, "jbsr %%z%d,%.246s",
25148 dest_operand_number, IDENTIFIER_POINTER (labelname));
25151 sprintf (buf, "bl %%z%d", dest_operand_number);
25155 /* Generate PIC and indirect symbol stubs. */
25158 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25160 unsigned int length;
25161 char *symbol_name, *lazy_ptr_name;
25162 char *local_label_0;
25163 static int label = 0;
25165 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25166 symb = (*targetm.strip_name_encoding) (symb);
25169 length = strlen (symb);
25170 symbol_name = XALLOCAVEC (char, length + 32);
25171 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25173 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25174 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25177 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25179 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25183 fprintf (file, "\t.align 5\n");
25185 fprintf (file, "%s:\n", stub);
25186 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25189 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25190 sprintf (local_label_0, "\"L%011d$spb\"", label);
25192 fprintf (file, "\tmflr r0\n");
25193 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25194 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25195 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25196 lazy_ptr_name, local_label_0);
25197 fprintf (file, "\tmtlr r0\n");
25198 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25199 (TARGET_64BIT ? "ldu" : "lwzu"),
25200 lazy_ptr_name, local_label_0);
25201 fprintf (file, "\tmtctr r12\n");
25202 fprintf (file, "\tbctr\n");
25206 fprintf (file, "\t.align 4\n");
25208 fprintf (file, "%s:\n", stub);
25209 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25211 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25212 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25213 (TARGET_64BIT ? "ldu" : "lwzu"),
25215 fprintf (file, "\tmtctr r12\n");
25216 fprintf (file, "\tbctr\n");
25219 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25220 fprintf (file, "%s:\n", lazy_ptr_name);
25221 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25222 fprintf (file, "%sdyld_stub_binding_helper\n",
25223 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25226 /* Legitimize PIC addresses. If the address is already
25227 position-independent, we return ORIG. Newly generated
25228 position-independent addresses go into a reg. This is REG if non
25229 zero, otherwise we allocate register(s) as necessary. */
25231 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25234 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25239 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25240 reg = gen_reg_rtx (Pmode);
25242 if (GET_CODE (orig) == CONST)
25246 if (GET_CODE (XEXP (orig, 0)) == PLUS
25247 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25250 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25252 /* Use a different reg for the intermediate value, as
25253 it will be marked UNCHANGING. */
25254 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25255 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25258 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25261 if (GET_CODE (offset) == CONST_INT)
25263 if (SMALL_INT (offset))
25264 return plus_constant (base, INTVAL (offset));
25265 else if (! reload_in_progress && ! reload_completed)
25266 offset = force_reg (Pmode, offset);
25269 rtx mem = force_const_mem (Pmode, orig);
25270 return machopic_legitimize_pic_address (mem, Pmode, reg);
25273 return gen_rtx_PLUS (Pmode, base, offset);
25276 /* Fall back on generic machopic code. */
25277 return machopic_legitimize_pic_address (orig, mode, reg);
25280 /* Output a .machine directive for the Darwin assembler, and call
25281 the generic start_file routine. */
25284 rs6000_darwin_file_start (void)
25286 static const struct
25292 { "ppc64", "ppc64", MASK_64BIT },
25293 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25294 { "power4", "ppc970", 0 },
25295 { "G5", "ppc970", 0 },
25296 { "7450", "ppc7450", 0 },
25297 { "7400", "ppc7400", MASK_ALTIVEC },
25298 { "G4", "ppc7400", 0 },
25299 { "750", "ppc750", 0 },
25300 { "740", "ppc750", 0 },
25301 { "G3", "ppc750", 0 },
25302 { "604e", "ppc604e", 0 },
25303 { "604", "ppc604", 0 },
25304 { "603e", "ppc603", 0 },
25305 { "603", "ppc603", 0 },
25306 { "601", "ppc601", 0 },
25307 { NULL, "ppc", 0 } };
25308 const char *cpu_id = "";
25311 rs6000_file_start ();
25312 darwin_file_start ();
25314 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25316 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25317 cpu_id = rs6000_default_cpu;
25319 if (global_options_set.x_rs6000_cpu_index)
25320 cpu_id = processor_target_table[rs6000_cpu_index].name;
25322 /* Look through the mapping array. Pick the first name that either
25323 matches the argument, has a bit set in IF_SET that is also set
25324 in the target flags, or has a NULL name. */
25327 while (mapping[i].arg != NULL
25328 && strcmp (mapping[i].arg, cpu_id) != 0
25329 && (mapping[i].if_set & target_flags) == 0)
25332 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25335 #endif /* TARGET_MACHO */
25339 rs6000_elf_reloc_rw_mask (void)
25343 else if (DEFAULT_ABI == ABI_AIX)
25349 /* Record an element in the table of global constructors. SYMBOL is
25350 a SYMBOL_REF of the function to be called; PRIORITY is a number
25351 between 0 and MAX_INIT_PRIORITY.
25353 This differs from default_named_section_asm_out_constructor in
25354 that we have special handling for -mrelocatable. */
25357 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25359 const char *section = ".ctors";
25362 if (priority != DEFAULT_INIT_PRIORITY)
25364 sprintf (buf, ".ctors.%.5u",
25365 /* Invert the numbering so the linker puts us in the proper
25366 order; constructors are run from right to left, and the
25367 linker sorts in increasing order. */
25368 MAX_INIT_PRIORITY - priority);
25372 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25373 assemble_align (POINTER_SIZE);
25375 if (TARGET_RELOCATABLE)
25377 fputs ("\t.long (", asm_out_file);
25378 output_addr_const (asm_out_file, symbol);
25379 fputs (")@fixup\n", asm_out_file);
25382 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25386 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25388 const char *section = ".dtors";
25391 if (priority != DEFAULT_INIT_PRIORITY)
25393 sprintf (buf, ".dtors.%.5u",
25394 /* Invert the numbering so the linker puts us in the proper
25395 order; constructors are run from right to left, and the
25396 linker sorts in increasing order. */
25397 MAX_INIT_PRIORITY - priority);
25401 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25402 assemble_align (POINTER_SIZE);
25404 if (TARGET_RELOCATABLE)
25406 fputs ("\t.long (", asm_out_file);
25407 output_addr_const (asm_out_file, symbol);
25408 fputs (")@fixup\n", asm_out_file);
25411 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25415 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25419 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25420 ASM_OUTPUT_LABEL (file, name);
25421 fputs (DOUBLE_INT_ASM_OP, file);
25422 rs6000_output_function_entry (file, name);
25423 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25426 fputs ("\t.size\t", file);
25427 assemble_name (file, name);
25428 fputs (",24\n\t.type\t.", file);
25429 assemble_name (file, name);
25430 fputs (",@function\n", file);
25431 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25433 fputs ("\t.globl\t.", file);
25434 assemble_name (file, name);
25439 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25440 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25441 rs6000_output_function_entry (file, name);
25442 fputs (":\n", file);
25446 if (TARGET_RELOCATABLE
25447 && !TARGET_SECURE_PLT
25448 && (get_pool_size () != 0 || crtl->profile)
25453 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25455 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25456 fprintf (file, "\t.long ");
25457 assemble_name (file, buf);
25459 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25460 assemble_name (file, buf);
25464 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25465 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25467 if (DEFAULT_ABI == ABI_AIX)
25469 const char *desc_name, *orig_name;
25471 orig_name = (*targetm.strip_name_encoding) (name);
25472 desc_name = orig_name;
25473 while (*desc_name == '.')
25476 if (TREE_PUBLIC (decl))
25477 fprintf (file, "\t.globl %s\n", desc_name);
25479 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25480 fprintf (file, "%s:\n", desc_name);
25481 fprintf (file, "\t.long %s\n", orig_name);
25482 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25483 if (DEFAULT_ABI == ABI_AIX)
25484 fputs ("\t.long 0\n", file);
25485 fprintf (file, "\t.previous\n");
25487 ASM_OUTPUT_LABEL (file, name);
25491 rs6000_elf_file_end (void)
25493 #ifdef HAVE_AS_GNU_ATTRIBUTE
25494 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25496 if (rs6000_passes_float)
25497 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25498 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25499 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25501 if (rs6000_passes_vector)
25502 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25503 (TARGET_ALTIVEC_ABI ? 2
25504 : TARGET_SPE_ABI ? 3
25506 if (rs6000_returns_struct)
25507 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25508 aix_struct_return ? 2 : 1);
25511 #ifdef POWERPC_LINUX
25513 file_end_indicate_exec_stack ();
25520 rs6000_xcoff_asm_output_anchor (rtx symbol)
25524 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25525 SYMBOL_REF_BLOCK_OFFSET (symbol));
25526 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25530 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25532 fputs (GLOBAL_ASM_OP, stream);
25533 RS6000_OUTPUT_BASENAME (stream, name);
25534 putc ('\n', stream);
25537 /* A get_unnamed_decl callback, used for read-only sections. PTR
25538 points to the section string variable. */
25541 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25543 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25544 *(const char *const *) directive,
25545 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25548 /* Likewise for read-write sections. */
25551 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25553 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25554 *(const char *const *) directive,
25555 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25558 /* A get_unnamed_section callback, used for switching to toc_section. */
25561 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25563 if (TARGET_MINIMAL_TOC)
25565 /* toc_section is always selected at least once from
25566 rs6000_xcoff_file_start, so this is guaranteed to
25567 always be defined once and only once in each file. */
25568 if (!toc_initialized)
25570 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25571 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25572 toc_initialized = 1;
25574 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25575 (TARGET_32BIT ? "" : ",3"));
25578 fputs ("\t.toc\n", asm_out_file);
25581 /* Implement TARGET_ASM_INIT_SECTIONS. */
25584 rs6000_xcoff_asm_init_sections (void)
25586 read_only_data_section
25587 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25588 &xcoff_read_only_section_name);
25590 private_data_section
25591 = get_unnamed_section (SECTION_WRITE,
25592 rs6000_xcoff_output_readwrite_section_asm_op,
25593 &xcoff_private_data_section_name);
25595 read_only_private_data_section
25596 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25597 &xcoff_private_data_section_name);
25600 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25602 readonly_data_section = read_only_data_section;
25603 exception_section = data_section;
25607 rs6000_xcoff_reloc_rw_mask (void)
25613 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25614 tree decl ATTRIBUTE_UNUSED)
25617 static const char * const suffix[3] = { "PR", "RO", "RW" };
25619 if (flags & SECTION_CODE)
25621 else if (flags & SECTION_WRITE)
25626 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25627 (flags & SECTION_CODE) ? "." : "",
25628 name, suffix[smclass], flags & SECTION_ENTSIZE);
25632 rs6000_xcoff_select_section (tree decl, int reloc,
25633 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25635 if (decl_readonly_section (decl, reloc))
25637 if (TREE_PUBLIC (decl))
25638 return read_only_data_section;
25640 return read_only_private_data_section;
25644 if (TREE_PUBLIC (decl))
25645 return data_section;
25647 return private_data_section;
25652 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25656 /* Use select_section for private and uninitialized data. */
25657 if (!TREE_PUBLIC (decl)
25658 || DECL_COMMON (decl)
25659 || DECL_INITIAL (decl) == NULL_TREE
25660 || DECL_INITIAL (decl) == error_mark_node
25661 || (flag_zero_initialized_in_bss
25662 && initializer_zerop (DECL_INITIAL (decl))))
25665 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25666 name = (*targetm.strip_name_encoding) (name);
25667 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25670 /* Select section for constant in constant pool.
25672 On RS/6000, all constants are in the private read-only data area.
25673 However, if this is being placed in the TOC it must be output as a
25677 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25678 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25680 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25681 return toc_section;
25683 return read_only_private_data_section;
25686 /* Remove any trailing [DS] or the like from the symbol name. */
25688 static const char *
25689 rs6000_xcoff_strip_name_encoding (const char *name)
25694 len = strlen (name);
25695 if (name[len - 1] == ']')
25696 return ggc_alloc_string (name, len - 4);
25701 /* Section attributes. AIX is always PIC. */
25703 static unsigned int
25704 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25706 unsigned int align;
25707 unsigned int flags = default_section_type_flags (decl, name, reloc);
25709 /* Align to at least UNIT size. */
25710 if (flags & SECTION_CODE)
25711 align = MIN_UNITS_PER_WORD;
25713 /* Increase alignment of large objects if not already stricter. */
25714 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25715 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25716 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25718 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25721 /* Output at beginning of assembler file.
25723 Initialize the section names for the RS/6000 at this point.
25725 Specify filename, including full path, to assembler.
25727 We want to go into the TOC section so at least one .toc will be emitted.
25728 Also, in order to output proper .bs/.es pairs, we need at least one static
25729 [RW] section emitted.
25731 Finally, declare mcount when profiling to make the assembler happy. */
25734 rs6000_xcoff_file_start (void)
25736 rs6000_gen_section_name (&xcoff_bss_section_name,
25737 main_input_filename, ".bss_");
25738 rs6000_gen_section_name (&xcoff_private_data_section_name,
25739 main_input_filename, ".rw_");
25740 rs6000_gen_section_name (&xcoff_read_only_section_name,
25741 main_input_filename, ".ro_");
25743 fputs ("\t.file\t", asm_out_file);
25744 output_quoted_string (asm_out_file, main_input_filename);
25745 fputc ('\n', asm_out_file);
25746 if (write_symbols != NO_DEBUG)
25747 switch_to_section (private_data_section);
25748 switch_to_section (text_section);
25750 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25751 rs6000_file_start ();
25754 /* Output at end of assembler file.
25755 On the RS/6000, referencing data should automatically pull in text. */
25758 rs6000_xcoff_file_end (void)
25760 switch_to_section (text_section);
25761 fputs ("_section_.text:\n", asm_out_file);
25762 switch_to_section (data_section);
25763 fputs (TARGET_32BIT
25764 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25767 #endif /* TARGET_XCOFF */
25769 /* Compute a (partial) cost for rtx X. Return true if the complete
25770 cost has been computed, and false if subexpressions should be
25771 scanned. In either case, *TOTAL contains the cost result. */
25774 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25777 enum machine_mode mode = GET_MODE (x);
25781 /* On the RS/6000, if it is valid in the insn, it is free. */
25783 if (((outer_code == SET
25784 || outer_code == PLUS
25785 || outer_code == MINUS)
25786 && (satisfies_constraint_I (x)
25787 || satisfies_constraint_L (x)))
25788 || (outer_code == AND
25789 && (satisfies_constraint_K (x)
25791 ? satisfies_constraint_L (x)
25792 : satisfies_constraint_J (x))
25793 || mask_operand (x, mode)
25795 && mask64_operand (x, DImode))))
25796 || ((outer_code == IOR || outer_code == XOR)
25797 && (satisfies_constraint_K (x)
25799 ? satisfies_constraint_L (x)
25800 : satisfies_constraint_J (x))))
25801 || outer_code == ASHIFT
25802 || outer_code == ASHIFTRT
25803 || outer_code == LSHIFTRT
25804 || outer_code == ROTATE
25805 || outer_code == ROTATERT
25806 || outer_code == ZERO_EXTRACT
25807 || (outer_code == MULT
25808 && satisfies_constraint_I (x))
25809 || ((outer_code == DIV || outer_code == UDIV
25810 || outer_code == MOD || outer_code == UMOD)
25811 && exact_log2 (INTVAL (x)) >= 0)
25812 || (outer_code == COMPARE
25813 && (satisfies_constraint_I (x)
25814 || satisfies_constraint_K (x)))
25815 || ((outer_code == EQ || outer_code == NE)
25816 && (satisfies_constraint_I (x)
25817 || satisfies_constraint_K (x)
25819 ? satisfies_constraint_L (x)
25820 : satisfies_constraint_J (x))))
25821 || (outer_code == GTU
25822 && satisfies_constraint_I (x))
25823 || (outer_code == LTU
25824 && satisfies_constraint_P (x)))
25829 else if ((outer_code == PLUS
25830 && reg_or_add_cint_operand (x, VOIDmode))
25831 || (outer_code == MINUS
25832 && reg_or_sub_cint_operand (x, VOIDmode))
25833 || ((outer_code == SET
25834 || outer_code == IOR
25835 || outer_code == XOR)
25837 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25839 *total = COSTS_N_INSNS (1);
25845 if (mode == DImode && code == CONST_DOUBLE)
25847 if ((outer_code == IOR || outer_code == XOR)
25848 && CONST_DOUBLE_HIGH (x) == 0
25849 && (CONST_DOUBLE_LOW (x)
25850 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25855 else if ((outer_code == AND && and64_2_operand (x, DImode))
25856 || ((outer_code == SET
25857 || outer_code == IOR
25858 || outer_code == XOR)
25859 && CONST_DOUBLE_HIGH (x) == 0))
25861 *total = COSTS_N_INSNS (1);
25871 /* When optimizing for size, MEM should be slightly more expensive
25872 than generating address, e.g., (plus (reg) (const)).
25873 L1 cache latency is about two instructions. */
25874 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25883 if (FLOAT_MODE_P (mode))
25884 *total = rs6000_cost->fp;
25886 *total = COSTS_N_INSNS (1);
25890 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25891 && satisfies_constraint_I (XEXP (x, 1)))
25893 if (INTVAL (XEXP (x, 1)) >= -256
25894 && INTVAL (XEXP (x, 1)) <= 255)
25895 *total = rs6000_cost->mulsi_const9;
25897 *total = rs6000_cost->mulsi_const;
25899 else if (mode == SFmode)
25900 *total = rs6000_cost->fp;
25901 else if (FLOAT_MODE_P (mode))
25902 *total = rs6000_cost->dmul;
25903 else if (mode == DImode)
25904 *total = rs6000_cost->muldi;
25906 *total = rs6000_cost->mulsi;
25910 if (mode == SFmode)
25911 *total = rs6000_cost->fp;
25913 *total = rs6000_cost->dmul;
25918 if (FLOAT_MODE_P (mode))
25920 *total = mode == DFmode ? rs6000_cost->ddiv
25921 : rs6000_cost->sdiv;
25928 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25929 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25931 if (code == DIV || code == MOD)
25933 *total = COSTS_N_INSNS (2);
25936 *total = COSTS_N_INSNS (1);
25940 if (GET_MODE (XEXP (x, 1)) == DImode)
25941 *total = rs6000_cost->divdi;
25943 *total = rs6000_cost->divsi;
25945 /* Add in shift and subtract for MOD. */
25946 if (code == MOD || code == UMOD)
25947 *total += COSTS_N_INSNS (2);
25952 *total = COSTS_N_INSNS (4);
25956 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25960 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25964 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25976 *total = COSTS_N_INSNS (1);
25984 /* Handle mul_highpart. */
25985 if (outer_code == TRUNCATE
25986 && GET_CODE (XEXP (x, 0)) == MULT)
25988 if (mode == DImode)
25989 *total = rs6000_cost->muldi;
25991 *total = rs6000_cost->mulsi;
25994 else if (outer_code == AND)
25997 *total = COSTS_N_INSNS (1);
26002 if (GET_CODE (XEXP (x, 0)) == MEM)
26005 *total = COSTS_N_INSNS (1);
26011 if (!FLOAT_MODE_P (mode))
26013 *total = COSTS_N_INSNS (1);
26019 case UNSIGNED_FLOAT:
26022 case FLOAT_TRUNCATE:
26023 *total = rs6000_cost->fp;
26027 if (mode == DFmode)
26030 *total = rs6000_cost->fp;
26034 switch (XINT (x, 1))
26037 *total = rs6000_cost->fp;
26049 *total = COSTS_N_INSNS (1);
26052 else if (FLOAT_MODE_P (mode)
26053 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26055 *total = rs6000_cost->fp;
26063 /* Carry bit requires mode == Pmode.
26064 NEG or PLUS already counted so only add one. */
26066 && (outer_code == NEG || outer_code == PLUS))
26068 *total = COSTS_N_INSNS (1);
26071 if (outer_code == SET)
26073 if (XEXP (x, 1) == const0_rtx)
26075 if (TARGET_ISEL && !TARGET_MFCRF)
26076 *total = COSTS_N_INSNS (8);
26078 *total = COSTS_N_INSNS (2);
26081 else if (mode == Pmode)
26083 *total = COSTS_N_INSNS (3);
26092 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26094 if (TARGET_ISEL && !TARGET_MFCRF)
26095 *total = COSTS_N_INSNS (8);
26097 *total = COSTS_N_INSNS (2);
26101 if (outer_code == COMPARE)
26115 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26118 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26121 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26124 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26125 "total = %d, speed = %s, x:\n",
26126 ret ? "complete" : "scan inner",
26127 GET_RTX_NAME (code),
26128 GET_RTX_NAME (outer_code),
26130 speed ? "true" : "false");
26137 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26140 rs6000_debug_address_cost (rtx x, bool speed)
26142 int ret = TARGET_ADDRESS_COST (x, speed);
26144 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26145 ret, speed ? "true" : "false");
26152 /* A C expression returning the cost of moving data from a register of class
26153 CLASS1 to one of CLASS2. */
26156 rs6000_register_move_cost (enum machine_mode mode,
26157 reg_class_t from, reg_class_t to)
26161 if (TARGET_DEBUG_COST)
26164 /* Moves from/to GENERAL_REGS. */
26165 if (reg_classes_intersect_p (to, GENERAL_REGS)
26166 || reg_classes_intersect_p (from, GENERAL_REGS))
26168 reg_class_t rclass = from;
26170 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26173 if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
26174 ret = (rs6000_memory_move_cost (mode, rclass, false)
26175 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26177 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26179 else if (rclass == CR_REGS)
26182 /* For those processors that have slow LR/CTR moves, make them more
26183 expensive than memory in order to bias spills to memory .*/
26184 else if ((rs6000_cpu == PROCESSOR_POWER6
26185 || rs6000_cpu == PROCESSOR_POWER7)
26186 && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
26187 ret = 6 * hard_regno_nregs[0][mode];
26190 /* A move will cost one instruction per GPR moved. */
26191 ret = 2 * hard_regno_nregs[0][mode];
26194 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26195 else if (VECTOR_UNIT_VSX_P (mode)
26196 && reg_classes_intersect_p (to, VSX_REGS)
26197 && reg_classes_intersect_p (from, VSX_REGS))
26198 ret = 2 * hard_regno_nregs[32][mode];
26200 /* Moving between two similar registers is just one instruction. */
26201 else if (reg_classes_intersect_p (to, from))
26202 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26204 /* Everything else has to go through GENERAL_REGS. */
26206 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26207 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26209 if (TARGET_DEBUG_COST)
26211 if (dbg_cost_ctrl == 1)
26213 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26214 ret, GET_MODE_NAME (mode), reg_class_names[from],
26215 reg_class_names[to]);
26222 /* A C expressions returning the cost of moving data of MODE from a register to
26226 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26227 bool in ATTRIBUTE_UNUSED)
26231 if (TARGET_DEBUG_COST)
26234 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26235 ret = 4 * hard_regno_nregs[0][mode];
26236 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26237 ret = 4 * hard_regno_nregs[32][mode];
26238 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26239 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26241 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26243 if (TARGET_DEBUG_COST)
26245 if (dbg_cost_ctrl == 1)
26247 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26248 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26255 /* Returns a code for a target-specific builtin that implements
26256 reciprocal of the function, or NULL_TREE if not available. */
26259 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26260 bool sqrt ATTRIBUTE_UNUSED)
26262 if (optimize_insn_for_size_p ())
26268 case VSX_BUILTIN_XVSQRTDP:
26269 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26272 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26274 case VSX_BUILTIN_XVSQRTSP:
26275 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26278 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26287 case BUILT_IN_SQRT:
26288 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26291 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26293 case BUILT_IN_SQRTF:
26294 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26297 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26304 /* Load up a constant. If the mode is a vector mode, splat the value across
26305 all of the vector elements. */
26308 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26312 if (mode == SFmode || mode == DFmode)
26314 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26315 reg = force_reg (mode, d);
26317 else if (mode == V4SFmode)
26319 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26320 rtvec v = gen_rtvec (4, d, d, d, d);
26321 reg = gen_reg_rtx (mode);
26322 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26324 else if (mode == V2DFmode)
26326 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26327 rtvec v = gen_rtvec (2, d, d);
26328 reg = gen_reg_rtx (mode);
26329 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26332 gcc_unreachable ();
26337 /* Generate an FMA instruction. */
26340 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26342 enum machine_mode mode = GET_MODE (target);
26345 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26346 gcc_assert (dst != NULL);
26349 emit_move_insn (target, dst);
26352 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26355 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26357 enum machine_mode mode = GET_MODE (target);
26360 /* Altivec does not support fms directly;
26361 generate in terms of fma in that case. */
26362 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26363 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26366 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26367 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26369 gcc_assert (dst != NULL);
26372 emit_move_insn (target, dst);
26375 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26378 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26380 enum machine_mode mode = GET_MODE (dst);
26383 /* This is a tad more complicated, since the fnma_optab is for
26384 a different expression: fma(-m1, m2, a), which is the same
26385 thing except in the case of signed zeros.
26387 Fortunately we know that if FMA is supported that FNMSUB is
26388 also supported in the ISA. Just expand it directly. */
26390 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26392 r = gen_rtx_NEG (mode, a);
26393 r = gen_rtx_FMA (mode, m1, m2, r);
26394 r = gen_rtx_NEG (mode, r);
26395 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26398 /* Newton-Raphson approximation of floating point divide with just 2 passes
26399 (either single precision floating point, or newer machines with higher
26400 accuracy estimates). Support both scalar and vector divide. Assumes no
26401 trapping math and finite arguments. */
26404 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26406 enum machine_mode mode = GET_MODE (dst);
26407 rtx x0, e0, e1, y1, u0, v0;
26408 enum insn_code code = optab_handler (smul_optab, mode);
26409 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26410 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26412 gcc_assert (code != CODE_FOR_nothing);
26414 /* x0 = 1./d estimate */
26415 x0 = gen_reg_rtx (mode);
26416 emit_insn (gen_rtx_SET (VOIDmode, x0,
26417 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26420 e0 = gen_reg_rtx (mode);
26421 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26423 e1 = gen_reg_rtx (mode);
26424 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26426 y1 = gen_reg_rtx (mode);
26427 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26429 u0 = gen_reg_rtx (mode);
26430 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26432 v0 = gen_reg_rtx (mode);
26433 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26435 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26438 /* Newton-Raphson approximation of floating point divide that has a low
26439 precision estimate. Assumes no trapping math and finite arguments. */
26442 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26444 enum machine_mode mode = GET_MODE (dst);
26445 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26446 enum insn_code code = optab_handler (smul_optab, mode);
26447 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26449 gcc_assert (code != CODE_FOR_nothing);
26451 one = rs6000_load_constant_and_splat (mode, dconst1);
26453 /* x0 = 1./d estimate */
26454 x0 = gen_reg_rtx (mode);
26455 emit_insn (gen_rtx_SET (VOIDmode, x0,
26456 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26459 e0 = gen_reg_rtx (mode);
26460 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26462 y1 = gen_reg_rtx (mode);
26463 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26465 e1 = gen_reg_rtx (mode);
26466 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26468 y2 = gen_reg_rtx (mode);
26469 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26471 e2 = gen_reg_rtx (mode);
26472 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26474 y3 = gen_reg_rtx (mode);
26475 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26477 u0 = gen_reg_rtx (mode);
26478 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26480 v0 = gen_reg_rtx (mode);
26481 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26483 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26486 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26487 add a reg_note saying that this was a division. Support both scalar and
26488 vector divide. Assumes no trapping math and finite arguments. */
26491 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26493 enum machine_mode mode = GET_MODE (dst);
26495 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26496 rs6000_emit_swdiv_high_precision (dst, n, d);
26498 rs6000_emit_swdiv_low_precision (dst, n, d);
26501 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26504 /* Newton-Raphson approximation of single/double-precision floating point
26505 rsqrt. Assumes no trapping math and finite arguments. */
26508 rs6000_emit_swrsqrt (rtx dst, rtx src)
26510 enum machine_mode mode = GET_MODE (src);
26511 rtx x0 = gen_reg_rtx (mode);
26512 rtx y = gen_reg_rtx (mode);
26513 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26514 REAL_VALUE_TYPE dconst3_2;
26517 enum insn_code code = optab_handler (smul_optab, mode);
26518 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26520 gcc_assert (code != CODE_FOR_nothing);
26522 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26523 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26524 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26526 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26528 /* x0 = rsqrt estimate */
26529 emit_insn (gen_rtx_SET (VOIDmode, x0,
26530 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26533 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26534 rs6000_emit_msub (y, src, halfthree, src);
26536 for (i = 0; i < passes; i++)
26538 rtx x1 = gen_reg_rtx (mode);
26539 rtx u = gen_reg_rtx (mode);
26540 rtx v = gen_reg_rtx (mode);
26542 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26543 emit_insn (gen_mul (u, x0, x0));
26544 rs6000_emit_nmsub (v, y, u, halfthree);
26545 emit_insn (gen_mul (x1, x0, v));
26549 emit_move_insn (dst, x0);
26553 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26554 (Power7) targets. DST is the target, and SRC is the argument operand. */
26557 rs6000_emit_popcount (rtx dst, rtx src)
26559 enum machine_mode mode = GET_MODE (dst);
26562 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26563 if (TARGET_POPCNTD)
26565 if (mode == SImode)
26566 emit_insn (gen_popcntdsi2 (dst, src));
26568 emit_insn (gen_popcntddi2 (dst, src));
26572 tmp1 = gen_reg_rtx (mode);
26574 if (mode == SImode)
26576 emit_insn (gen_popcntbsi2 (tmp1, src));
26577 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26579 tmp2 = force_reg (SImode, tmp2);
26580 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26584 emit_insn (gen_popcntbdi2 (tmp1, src));
26585 tmp2 = expand_mult (DImode, tmp1,
26586 GEN_INT ((HOST_WIDE_INT)
26587 0x01010101 << 32 | 0x01010101),
26589 tmp2 = force_reg (DImode, tmp2);
26590 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26595 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26596 target, and SRC is the argument operand. */
26599 rs6000_emit_parity (rtx dst, rtx src)
26601 enum machine_mode mode = GET_MODE (dst);
26604 tmp = gen_reg_rtx (mode);
26606 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26609 if (mode == SImode)
26611 emit_insn (gen_popcntbsi2 (tmp, src));
26612 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26616 emit_insn (gen_popcntbdi2 (tmp, src));
26617 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26622 if (mode == SImode)
26624 /* Is mult+shift >= shift+xor+shift+xor? */
26625 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26627 rtx tmp1, tmp2, tmp3, tmp4;
26629 tmp1 = gen_reg_rtx (SImode);
26630 emit_insn (gen_popcntbsi2 (tmp1, src));
26632 tmp2 = gen_reg_rtx (SImode);
26633 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26634 tmp3 = gen_reg_rtx (SImode);
26635 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26637 tmp4 = gen_reg_rtx (SImode);
26638 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26639 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26642 rs6000_emit_popcount (tmp, src);
26643 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26647 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26648 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26650 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26652 tmp1 = gen_reg_rtx (DImode);
26653 emit_insn (gen_popcntbdi2 (tmp1, src));
26655 tmp2 = gen_reg_rtx (DImode);
26656 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26657 tmp3 = gen_reg_rtx (DImode);
26658 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26660 tmp4 = gen_reg_rtx (DImode);
26661 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26662 tmp5 = gen_reg_rtx (DImode);
26663 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26665 tmp6 = gen_reg_rtx (DImode);
26666 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26667 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26670 rs6000_emit_popcount (tmp, src);
26671 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26675 /* Return an RTX representing where to find the function value of a
26676 function returning MODE. */
26678 rs6000_complex_function_value (enum machine_mode mode)
26680 unsigned int regno;
26682 enum machine_mode inner = GET_MODE_INNER (mode);
26683 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26685 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26686 regno = FP_ARG_RETURN;
26689 regno = GP_ARG_RETURN;
26691 /* 32-bit is OK since it'll go in r3/r4. */
26692 if (TARGET_32BIT && inner_bytes >= 4)
26693 return gen_rtx_REG (mode, regno);
26696 if (inner_bytes >= 8)
26697 return gen_rtx_REG (mode, regno);
26699 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26701 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26702 GEN_INT (inner_bytes));
26703 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26706 /* Target hook for TARGET_FUNCTION_VALUE.
26708 On the SPE, both FPs and vectors are returned in r3.
26710 On RS/6000 an integer value is in r3 and a floating-point value is in
26711 fp1, unless -msoft-float. */
26714 rs6000_function_value (const_tree valtype,
26715 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26716 bool outgoing ATTRIBUTE_UNUSED)
26718 enum machine_mode mode;
26719 unsigned int regno;
26721 /* Special handling for structs in darwin64. */
26723 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26725 CUMULATIVE_ARGS valcum;
26729 valcum.fregno = FP_ARG_MIN_REG;
26730 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26731 /* Do a trial code generation as if this were going to be passed as
26732 an argument; if any part goes in memory, we return NULL. */
26733 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26736 /* Otherwise fall through to standard ABI rules. */
26739 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26741 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26742 return gen_rtx_PARALLEL (DImode,
26744 gen_rtx_EXPR_LIST (VOIDmode,
26745 gen_rtx_REG (SImode, GP_ARG_RETURN),
26747 gen_rtx_EXPR_LIST (VOIDmode,
26748 gen_rtx_REG (SImode,
26749 GP_ARG_RETURN + 1),
26752 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26754 return gen_rtx_PARALLEL (DCmode,
26756 gen_rtx_EXPR_LIST (VOIDmode,
26757 gen_rtx_REG (SImode, GP_ARG_RETURN),
26759 gen_rtx_EXPR_LIST (VOIDmode,
26760 gen_rtx_REG (SImode,
26761 GP_ARG_RETURN + 1),
26763 gen_rtx_EXPR_LIST (VOIDmode,
26764 gen_rtx_REG (SImode,
26765 GP_ARG_RETURN + 2),
26767 gen_rtx_EXPR_LIST (VOIDmode,
26768 gen_rtx_REG (SImode,
26769 GP_ARG_RETURN + 3),
26773 mode = TYPE_MODE (valtype);
26774 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26775 || POINTER_TYPE_P (valtype))
26776 mode = TARGET_32BIT ? SImode : DImode;
26778 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26779 /* _Decimal128 must use an even/odd register pair. */
26780 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26781 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26782 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26783 regno = FP_ARG_RETURN;
26784 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26785 && targetm.calls.split_complex_arg)
26786 return rs6000_complex_function_value (mode);
26787 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26788 return register is used in both cases, and we won't see V2DImode/V2DFmode
26789 for pure altivec, combine the two cases. */
26790 else if (TREE_CODE (valtype) == VECTOR_TYPE
26791 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26792 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
26793 regno = ALTIVEC_ARG_RETURN;
26794 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26795 && (mode == DFmode || mode == DCmode
26796 || mode == TFmode || mode == TCmode))
26797 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26799 regno = GP_ARG_RETURN;
26801 return gen_rtx_REG (mode, regno);
26804 /* Define how to find the value returned by a library function
26805 assuming the value has mode MODE. */
26807 rs6000_libcall_value (enum machine_mode mode)
26809 unsigned int regno;
26811 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26813 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26814 return gen_rtx_PARALLEL (DImode,
26816 gen_rtx_EXPR_LIST (VOIDmode,
26817 gen_rtx_REG (SImode, GP_ARG_RETURN),
26819 gen_rtx_EXPR_LIST (VOIDmode,
26820 gen_rtx_REG (SImode,
26821 GP_ARG_RETURN + 1),
26825 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26826 /* _Decimal128 must use an even/odd register pair. */
26827 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26828 else if (SCALAR_FLOAT_MODE_P (mode)
26829 && TARGET_HARD_FLOAT && TARGET_FPRS
26830 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26831 regno = FP_ARG_RETURN;
26832 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26833 return register is used in both cases, and we won't see V2DImode/V2DFmode
26834 for pure altivec, combine the two cases. */
26835 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
26836 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26837 regno = ALTIVEC_ARG_RETURN;
26838 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26839 return rs6000_complex_function_value (mode);
26840 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26841 && (mode == DFmode || mode == DCmode
26842 || mode == TFmode || mode == TCmode))
26843 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26845 regno = GP_ARG_RETURN;
26847 return gen_rtx_REG (mode, regno);
26851 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26852 Frame pointer elimination is automatically handled.
26854 For the RS/6000, if frame pointer elimination is being done, we would like
26855 to convert ap into fp, not sp.
26857 We need r30 if -mminimal-toc was specified, and there are constant pool
26861 rs6000_can_eliminate (const int from, const int to)
26863 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26864 ? ! frame_pointer_needed
26865 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26866 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26870 /* Define the offset between two registers, FROM to be eliminated and its
26871 replacement TO, at the start of a routine. */
26873 rs6000_initial_elimination_offset (int from, int to)
26875 rs6000_stack_t *info = rs6000_stack_info ();
26876 HOST_WIDE_INT offset;
26878 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26879 offset = info->push_p ? 0 : -info->total_size;
26880 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26882 offset = info->push_p ? 0 : -info->total_size;
26883 if (FRAME_GROWS_DOWNWARD)
26884 offset += info->fixed_size + info->vars_size + info->parm_size;
26886 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26887 offset = FRAME_GROWS_DOWNWARD
26888 ? info->fixed_size + info->vars_size + info->parm_size
26890 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26891 offset = info->total_size;
26892 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26893 offset = info->push_p ? info->total_size : 0;
26894 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26897 gcc_unreachable ();
26903 rs6000_dwarf_register_span (rtx reg)
26907 unsigned regno = REGNO (reg);
26908 enum machine_mode mode = GET_MODE (reg);
26912 && (SPE_VECTOR_MODE (GET_MODE (reg))
26913 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26914 && mode != SFmode && mode != SDmode && mode != SCmode)))
26919 regno = REGNO (reg);
26921 /* The duality of the SPE register size wreaks all kinds of havoc.
26922 This is a way of distinguishing r0 in 32-bits from r0 in
26924 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26925 gcc_assert (words <= 4);
26926 for (i = 0; i < words; i++, regno++)
26928 if (BYTES_BIG_ENDIAN)
26930 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26931 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26935 parts[2 * i] = gen_rtx_REG (SImode, regno);
26936 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26940 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26943 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26946 rs6000_init_dwarf_reg_sizes_extra (tree address)
26951 enum machine_mode mode = TYPE_MODE (char_type_node);
26952 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26953 rtx mem = gen_rtx_MEM (BLKmode, addr);
26954 rtx value = gen_int_mode (4, mode);
26956 for (i = 1201; i < 1232; i++)
26958 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26959 HOST_WIDE_INT offset
26960 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26962 emit_move_insn (adjust_address (mem, mode, offset), value);
26967 /* Map internal gcc register numbers to DWARF2 register numbers. */
26970 rs6000_dbx_register_number (unsigned int regno)
26972 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26974 if (regno == MQ_REGNO)
26976 if (regno == LR_REGNO)
26978 if (regno == CTR_REGNO)
26980 if (CR_REGNO_P (regno))
26981 return regno - CR0_REGNO + 86;
26982 if (regno == CA_REGNO)
26983 return 101; /* XER */
26984 if (ALTIVEC_REGNO_P (regno))
26985 return regno - FIRST_ALTIVEC_REGNO + 1124;
26986 if (regno == VRSAVE_REGNO)
26988 if (regno == VSCR_REGNO)
26990 if (regno == SPE_ACC_REGNO)
26992 if (regno == SPEFSCR_REGNO)
26994 /* SPE high reg number. We get these values of regno from
26995 rs6000_dwarf_register_span. */
26996 gcc_assert (regno >= 1200 && regno < 1232);
27000 /* target hook eh_return_filter_mode */
27001 static enum machine_mode
27002 rs6000_eh_return_filter_mode (void)
27004 return TARGET_32BIT ? SImode : word_mode;
27007 /* Target hook for scalar_mode_supported_p. */
27009 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27011 if (DECIMAL_FLOAT_MODE_P (mode))
27012 return default_decimal_float_supported_p ();
27014 return default_scalar_mode_supported_p (mode);
27017 /* Target hook for vector_mode_supported_p. */
27019 rs6000_vector_mode_supported_p (enum machine_mode mode)
27022 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27025 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27028 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27035 /* Target hook for invalid_arg_for_unprototyped_fn. */
27036 static const char *
27037 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27039 return (!rs6000_darwin64_abi
27041 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27042 && (funcdecl == NULL_TREE
27043 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27044 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27045 ? N_("AltiVec argument passed to unprototyped function")
27049 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27050 setup by using __stack_chk_fail_local hidden function instead of
27051 calling __stack_chk_fail directly. Otherwise it is better to call
27052 __stack_chk_fail directly. */
27054 static tree ATTRIBUTE_UNUSED
27055 rs6000_stack_protect_fail (void)
27057 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27058 ? default_hidden_stack_protect_fail ()
27059 : default_external_stack_protect_fail ();
27063 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27064 int num_operands ATTRIBUTE_UNUSED)
27066 if (rs6000_warn_cell_microcode)
27069 int insn_code_number = recog_memoized (insn);
27070 location_t location = locator_location (INSN_LOCATOR (insn));
27072 /* Punt on insns we cannot recognize. */
27073 if (insn_code_number < 0)
27076 temp = get_insn_template (insn_code_number, insn);
27078 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27079 warning_at (location, OPT_mwarn_cell_microcode,
27080 "emitting microcode insn %s\t[%s] #%d",
27081 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27082 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27083 warning_at (location, OPT_mwarn_cell_microcode,
27084 "emitting conditional microcode insn %s\t[%s] #%d",
27085 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27090 /* Mask options that we want to support inside of attribute((target)) and
27091 #pragma GCC target operations. Note, we do not include things like
27092 64/32-bit, endianess, hard/soft floating point, etc. that would have
27093 different calling sequences. */
27095 struct rs6000_opt_mask {
27096 const char *name; /* option name */
27097 int mask; /* mask to set */
27098 bool invert; /* invert sense of mask */
27099 bool valid_target; /* option is a target option */
27102 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27104 { "altivec", MASK_ALTIVEC, false, true },
27105 { "cmpb", MASK_CMPB, false, true },
27106 { "dlmzb", MASK_DLMZB, false, true },
27107 { "fprnd", MASK_FPRND, false, true },
27108 { "hard-dfp", MASK_DFP, false, true },
27109 { "isel", MASK_ISEL, false, true },
27110 { "mfcrf", MASK_MFCRF, false, true },
27111 { "mfpgpr", MASK_MFPGPR, false, true },
27112 { "mulhw", MASK_MULHW, false, true },
27113 { "multiple", MASK_MULTIPLE, false, true },
27114 { "update", MASK_NO_UPDATE, true , true },
27115 { "popcntb", MASK_POPCNTB, false, true },
27116 { "popcntd", MASK_POPCNTD, false, true },
27117 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27118 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27119 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27120 { "string", MASK_STRING, false, true },
27121 { "vsx", MASK_VSX, false, true },
27124 { "aix64", MASK_64BIT, false, false },
27125 { "aix32", MASK_64BIT, true, false },
27127 { "64", MASK_64BIT, false, false },
27128 { "32", MASK_64BIT, true, false },
27132 { "eabi", MASK_EABI, false, false },
27134 #ifdef MASK_LITTLE_ENDIAN
27135 { "little", MASK_LITTLE_ENDIAN, false, false },
27136 { "big", MASK_LITTLE_ENDIAN, true, false },
27138 #ifdef MASK_RELOCATABLE
27139 { "relocatable", MASK_RELOCATABLE, false, false },
27141 #ifdef MASK_STRICT_ALIGN
27142 { "strict-align", MASK_STRICT_ALIGN, false, false },
27144 { "power", MASK_POWER, false, false },
27145 { "power2", MASK_POWER2, false, false },
27146 { "powerpc", MASK_POWERPC, false, false },
27147 { "soft-float", MASK_SOFT_FLOAT, false, false },
27148 { "string", MASK_STRING, false, false },
27151 /* Option variables that we want to support inside attribute((target)) and
27152 #pragma GCC target operations. */
27154 struct rs6000_opt_var {
27155 const char *name; /* option name */
27156 size_t global_offset; /* offset of the option in global_options. */
27157 size_t target_offset; /* offset of the option in target optiosn. */
27160 static struct rs6000_opt_var const rs6000_opt_vars[] =
27163 offsetof (struct gcc_options, x_TARGET_FRIZ),
27164 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27165 { "avoid-indexed-addresses",
27166 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27167 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27169 offsetof (struct gcc_options, x_rs6000_paired_float),
27170 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27172 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27173 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27176 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27177 parsing. Return true if there were no errors. */
27180 rs6000_inner_target_options (tree args, bool attr_p)
27184 if (args == NULL_TREE)
27187 else if (TREE_CODE (args) == STRING_CST)
27189 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27192 while ((q = strtok (p, ",")) != NULL)
27194 bool error_p = false;
27195 bool not_valid_p = false;
27196 const char *cpu_opt = NULL;
27199 if (strncmp (q, "cpu=", 4) == 0)
27201 int cpu_index = rs6000_cpu_name_lookup (q+4);
27202 if (cpu_index >= 0)
27203 rs6000_cpu_index = cpu_index;
27210 else if (strncmp (q, "tune=", 5) == 0)
27212 int tune_index = rs6000_cpu_name_lookup (q+5);
27213 if (tune_index >= 0)
27214 rs6000_tune_index = tune_index;
27224 bool invert = false;
27228 if (strncmp (r, "no-", 3) == 0)
27234 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27235 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27237 int mask = rs6000_opt_masks[i].mask;
27239 if (!rs6000_opt_masks[i].valid_target)
27240 not_valid_p = true;
27244 target_flags_explicit |= mask;
27246 if (rs6000_opt_masks[i].invert)
27250 target_flags &= ~mask;
27252 target_flags |= mask;
27257 if (error_p && !not_valid_p)
27259 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27260 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27262 size_t j = rs6000_opt_vars[i].global_offset;
27263 ((int *) &global_options)[j] = !invert;
27272 const char *eprefix, *esuffix;
27277 eprefix = "__attribute__((__target__(";
27282 eprefix = "#pragma GCC target ";
27287 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27289 else if (not_valid_p)
27290 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27292 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27297 else if (TREE_CODE (args) == TREE_LIST)
27301 tree value = TREE_VALUE (args);
27304 bool ret2 = rs6000_inner_target_options (value, attr_p);
27308 args = TREE_CHAIN (args);
27310 while (args != NULL_TREE);
27314 gcc_unreachable ();
27319 /* Print out the target options as a list for -mdebug=target. */
27322 rs6000_debug_target_options (tree args, const char *prefix)
27324 if (args == NULL_TREE)
27325 fprintf (stderr, "%s<NULL>", prefix);
27327 else if (TREE_CODE (args) == STRING_CST)
27329 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27332 while ((q = strtok (p, ",")) != NULL)
27335 fprintf (stderr, "%s\"%s\"", prefix, q);
27340 else if (TREE_CODE (args) == TREE_LIST)
27344 tree value = TREE_VALUE (args);
27347 rs6000_debug_target_options (value, prefix);
27350 args = TREE_CHAIN (args);
27352 while (args != NULL_TREE);
27356 gcc_unreachable ();
27362 /* Hook to validate attribute((target("..."))). */
27365 rs6000_valid_attribute_p (tree fndecl,
27366 tree ARG_UNUSED (name),
27370 struct cl_target_option cur_target;
27372 tree old_optimize = build_optimization_node ();
27373 tree new_target, new_optimize;
27374 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27376 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27378 if (TARGET_DEBUG_TARGET)
27380 tree tname = DECL_NAME (fndecl);
27381 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27383 fprintf (stderr, "function: %.*s\n",
27384 (int) IDENTIFIER_LENGTH (tname),
27385 IDENTIFIER_POINTER (tname));
27387 fprintf (stderr, "function: unknown\n");
27389 fprintf (stderr, "args:");
27390 rs6000_debug_target_options (args, " ");
27391 fprintf (stderr, "\n");
27394 fprintf (stderr, "flags: 0x%x\n", flags);
27396 fprintf (stderr, "--------------------\n");
27399 old_optimize = build_optimization_node ();
27400 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27402 /* If the function changed the optimization levels as well as setting target
27403 options, start with the optimizations specified. */
27404 if (func_optimize && func_optimize != old_optimize)
27405 cl_optimization_restore (&global_options,
27406 TREE_OPTIMIZATION (func_optimize));
27408 /* The target attributes may also change some optimization flags, so update
27409 the optimization options if necessary. */
27410 cl_target_option_save (&cur_target, &global_options);
27411 rs6000_cpu_index = rs6000_tune_index = -1;
27412 ret = rs6000_inner_target_options (args, true);
27414 /* Set up any additional state. */
27417 ret = rs6000_option_override_internal (false);
27418 new_target = build_target_option_node ();
27423 new_optimize = build_optimization_node ();
27430 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27432 if (old_optimize != new_optimize)
27433 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27436 cl_target_option_restore (&global_options, &cur_target);
27438 if (old_optimize != new_optimize)
27439 cl_optimization_restore (&global_options,
27440 TREE_OPTIMIZATION (old_optimize));
27446 /* Hook to validate the current #pragma GCC target and set the state, and
27447 update the macros based on what was changed. If ARGS is NULL, then
27448 POP_TARGET is used to reset the options. */
27451 rs6000_pragma_target_parse (tree args, tree pop_target)
27456 if (TARGET_DEBUG_TARGET)
27458 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27459 fprintf (stderr, "args:");
27460 rs6000_debug_target_options (args, " ");
27461 fprintf (stderr, "\n");
27465 fprintf (stderr, "pop_target:\n");
27466 debug_tree (pop_target);
27469 fprintf (stderr, "pop_target: <NULL>\n");
27471 fprintf (stderr, "--------------------\n");
27477 cur_tree = ((pop_target)
27479 : target_option_default_node);
27480 cl_target_option_restore (&global_options,
27481 TREE_TARGET_OPTION (cur_tree));
27485 rs6000_cpu_index = rs6000_tune_index = -1;
27486 ret = rs6000_inner_target_options (args, false);
27487 cur_tree = build_target_option_node ();
27494 target_option_current_node = cur_tree;
27500 /* Remember the last target of rs6000_set_current_function. */
27501 static GTY(()) tree rs6000_previous_fndecl;
27503 /* Establish appropriate back-end context for processing the function
27504 FNDECL. The argument might be NULL to indicate processing at top
27505 level, outside of any function scope. */
27507 rs6000_set_current_function (tree fndecl)
27509 tree old_tree = (rs6000_previous_fndecl
27510 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27513 tree new_tree = (fndecl
27514 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27517 if (TARGET_DEBUG_TARGET)
27519 bool print_final = false;
27520 fprintf (stderr, "\n==================== rs6000_set_current_function");
27523 fprintf (stderr, ", fndecl %s (%p)",
27524 (DECL_NAME (fndecl)
27525 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27526 : "<unknown>"), (void *)fndecl);
27528 if (rs6000_previous_fndecl)
27529 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27531 fprintf (stderr, "\n");
27534 fprintf (stderr, "\nnew fndecl target specific options:\n");
27535 debug_tree (new_tree);
27536 print_final = true;
27541 fprintf (stderr, "\nold fndecl target specific options:\n");
27542 debug_tree (old_tree);
27543 print_final = true;
27547 fprintf (stderr, "--------------------\n");
27550 /* Only change the context if the function changes. This hook is called
27551 several times in the course of compiling a function, and we don't want to
27552 slow things down too much or call target_reinit when it isn't safe. */
27553 if (fndecl && fndecl != rs6000_previous_fndecl)
27555 rs6000_previous_fndecl = fndecl;
27556 if (old_tree == new_tree)
27561 cl_target_option_restore (&global_options,
27562 TREE_TARGET_OPTION (new_tree));
27568 struct cl_target_option *def
27569 = TREE_TARGET_OPTION (target_option_current_node);
27571 cl_target_option_restore (&global_options, def);
27578 /* Save the current options */
27581 rs6000_function_specific_save (struct cl_target_option *ptr)
27583 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27586 /* Restore the current options */
27589 rs6000_function_specific_restore (struct cl_target_option *ptr)
27591 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27592 (void) rs6000_option_override_internal (false);
27595 /* Print the current options */
27598 rs6000_function_specific_print (FILE *file, int indent,
27599 struct cl_target_option *ptr)
27602 int flags = ptr->x_target_flags;
27604 /* Print the various mask options. */
27605 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27606 if ((flags & rs6000_opt_masks[i].mask) != 0)
27608 flags &= ~ rs6000_opt_masks[i].mask;
27609 fprintf (file, "%*s-m%s%s\n", indent, "",
27610 rs6000_opt_masks[i].invert ? "no-" : "",
27611 rs6000_opt_masks[i].name);
27614 /* Print the various options that are variables. */
27615 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27617 size_t j = rs6000_opt_vars[i].target_offset;
27618 if (((signed char *) ptr)[j])
27619 fprintf (file, "%*s-m%s\n", indent, "",
27620 rs6000_opt_vars[i].name);
27625 /* Hook to determine if one function can safely inline another. */
27628 rs6000_can_inline_p (tree caller, tree callee)
27631 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27632 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27634 /* If callee has no option attributes, then it is ok to inline. */
27638 /* If caller has no option attributes, but callee does then it is not ok to
27640 else if (!caller_tree)
27645 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27646 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27648 /* Callee's options should a subset of the caller's, i.e. a vsx function
27649 can inline an altivec function but a non-vsx function can't inline a
27651 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27652 == callee_opts->x_target_flags)
27656 if (TARGET_DEBUG_TARGET)
27657 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27658 (DECL_NAME (caller)
27659 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27661 (DECL_NAME (callee)
27662 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27664 (ret ? "can" : "cannot"));
27669 /* Allocate a stack temp and fixup the address so it meets the particular
27670 memory requirements (either offetable or REG+REG addressing). */
27673 rs6000_allocate_stack_temp (enum machine_mode mode,
27674 bool offsettable_p,
27677 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27678 rtx addr = XEXP (stack, 0);
27679 int strict_p = (reload_in_progress || reload_completed);
27681 if (!legitimate_indirect_address_p (addr, strict_p))
27684 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27685 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27687 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27688 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27694 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27695 to such a form to deal with memory reference instructions like STFIWX that
27696 only take reg+reg addressing. */
27699 rs6000_address_for_fpconvert (rtx x)
27701 int strict_p = (reload_in_progress || reload_completed);
27704 gcc_assert (MEM_P (x));
27705 addr = XEXP (x, 0);
27706 if (! legitimate_indirect_address_p (addr, strict_p)
27707 && ! legitimate_indexed_address_p (addr, strict_p))
27709 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27711 rtx reg = XEXP (addr, 0);
27712 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27713 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27714 gcc_assert (REG_P (reg));
27715 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27718 else if (GET_CODE (addr) == PRE_MODIFY)
27720 rtx reg = XEXP (addr, 0);
27721 rtx expr = XEXP (addr, 1);
27722 gcc_assert (REG_P (reg));
27723 gcc_assert (GET_CODE (expr) == PLUS);
27724 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27728 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27734 /* Given a memory reference, if it is not in the form for altivec memory
27735 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27736 convert to the altivec format. */
27739 rs6000_address_for_altivec (rtx x)
27741 gcc_assert (MEM_P (x));
27742 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27744 rtx addr = XEXP (x, 0);
27745 int strict_p = (reload_in_progress || reload_completed);
27747 if (!legitimate_indexed_address_p (addr, strict_p)
27748 && !legitimate_indirect_address_p (addr, strict_p))
27749 addr = copy_to_mode_reg (Pmode, addr);
27751 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
27752 x = change_address (x, GET_MODE (x), addr);
27758 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27760 On the RS/6000, all integer constants are acceptable, most won't be valid
27761 for particular insns, though. Only easy FP constants are acceptable. */
27764 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
27766 if (rs6000_tls_referenced_p (x))
27769 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
27770 || GET_MODE (x) == VOIDmode
27771 || (TARGET_POWERPC64 && mode == DImode)
27772 || easy_fp_constant (x, mode)
27773 || easy_vector_constant (x, mode));
27776 #include "gt-rs6000.h"