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
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"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
257 traceback_default = 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC476 processors. */
516 struct processor_costs ppc476_cost = {
517 COSTS_N_INSNS (4), /* mulsi */
518 COSTS_N_INSNS (4), /* mulsi_const */
519 COSTS_N_INSNS (4), /* mulsi_const9 */
520 COSTS_N_INSNS (4), /* muldi */
521 COSTS_N_INSNS (11), /* divsi */
522 COSTS_N_INSNS (11), /* divdi */
523 COSTS_N_INSNS (6), /* fp */
524 COSTS_N_INSNS (6), /* dmul */
525 COSTS_N_INSNS (19), /* sdiv */
526 COSTS_N_INSNS (33), /* ddiv */
527 32, /* l1 cache line size */
533 /* Instruction costs on PPC601 processors. */
535 struct processor_costs ppc601_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (5), /* mulsi_const */
538 COSTS_N_INSNS (5), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (36), /* divsi */
541 COSTS_N_INSNS (36), /* divdi */
542 COSTS_N_INSNS (4), /* fp */
543 COSTS_N_INSNS (5), /* dmul */
544 COSTS_N_INSNS (17), /* sdiv */
545 COSTS_N_INSNS (31), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC603 processors. */
554 struct processor_costs ppc603_cost = {
555 COSTS_N_INSNS (5), /* mulsi */
556 COSTS_N_INSNS (3), /* mulsi_const */
557 COSTS_N_INSNS (2), /* mulsi_const9 */
558 COSTS_N_INSNS (5), /* muldi */
559 COSTS_N_INSNS (37), /* divsi */
560 COSTS_N_INSNS (37), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (4), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (33), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604 processors. */
573 struct processor_costs ppc604_cost = {
574 COSTS_N_INSNS (4), /* mulsi */
575 COSTS_N_INSNS (4), /* mulsi_const */
576 COSTS_N_INSNS (4), /* mulsi_const9 */
577 COSTS_N_INSNS (4), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC604e processors. */
592 struct processor_costs ppc604e_cost = {
593 COSTS_N_INSNS (2), /* mulsi */
594 COSTS_N_INSNS (2), /* mulsi_const */
595 COSTS_N_INSNS (2), /* mulsi_const9 */
596 COSTS_N_INSNS (2), /* muldi */
597 COSTS_N_INSNS (20), /* divsi */
598 COSTS_N_INSNS (20), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 32, /* cache line size */
609 /* Instruction costs on PPC620 processors. */
611 struct processor_costs ppc620_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (18), /* sdiv */
621 COSTS_N_INSNS (32), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on PPC630 processors. */
630 struct processor_costs ppc630_cost = {
631 COSTS_N_INSNS (5), /* mulsi */
632 COSTS_N_INSNS (4), /* mulsi_const */
633 COSTS_N_INSNS (3), /* mulsi_const9 */
634 COSTS_N_INSNS (7), /* muldi */
635 COSTS_N_INSNS (21), /* divsi */
636 COSTS_N_INSNS (37), /* divdi */
637 COSTS_N_INSNS (3), /* fp */
638 COSTS_N_INSNS (3), /* dmul */
639 COSTS_N_INSNS (17), /* sdiv */
640 COSTS_N_INSNS (21), /* ddiv */
641 128, /* cache line size */
647 /* Instruction costs on Cell processor. */
648 /* COSTS_N_INSNS (1) ~ one add. */
650 struct processor_costs ppccell_cost = {
651 COSTS_N_INSNS (9/2)+2, /* mulsi */
652 COSTS_N_INSNS (6/2), /* mulsi_const */
653 COSTS_N_INSNS (6/2), /* mulsi_const9 */
654 COSTS_N_INSNS (15/2)+2, /* muldi */
655 COSTS_N_INSNS (38/2), /* divsi */
656 COSTS_N_INSNS (70/2), /* divdi */
657 COSTS_N_INSNS (10/2), /* fp */
658 COSTS_N_INSNS (10/2), /* dmul */
659 COSTS_N_INSNS (74/2), /* sdiv */
660 COSTS_N_INSNS (74/2), /* ddiv */
661 128, /* cache line size */
667 /* Instruction costs on PPC750 and PPC7400 processors. */
669 struct processor_costs ppc750_cost = {
670 COSTS_N_INSNS (5), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (2), /* mulsi_const9 */
673 COSTS_N_INSNS (5), /* muldi */
674 COSTS_N_INSNS (17), /* divsi */
675 COSTS_N_INSNS (17), /* divdi */
676 COSTS_N_INSNS (3), /* fp */
677 COSTS_N_INSNS (3), /* dmul */
678 COSTS_N_INSNS (17), /* sdiv */
679 COSTS_N_INSNS (31), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC7450 processors. */
688 struct processor_costs ppc7450_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (3), /* mulsi_const */
691 COSTS_N_INSNS (3), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (23), /* divsi */
694 COSTS_N_INSNS (23), /* divdi */
695 COSTS_N_INSNS (5), /* fp */
696 COSTS_N_INSNS (5), /* dmul */
697 COSTS_N_INSNS (21), /* sdiv */
698 COSTS_N_INSNS (35), /* ddiv */
699 32, /* cache line size */
705 /* Instruction costs on PPC8540 processors. */
707 struct processor_costs ppc8540_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (4), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (29), /* sdiv */
717 COSTS_N_INSNS (29), /* ddiv */
718 32, /* cache line size */
721 1, /* prefetch streams /*/
724 /* Instruction costs on E300C2 and E300C3 cores. */
726 struct processor_costs ppce300c2c3_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (19), /* divsi */
732 COSTS_N_INSNS (19), /* divdi */
733 COSTS_N_INSNS (3), /* fp */
734 COSTS_N_INSNS (4), /* dmul */
735 COSTS_N_INSNS (18), /* sdiv */
736 COSTS_N_INSNS (33), /* ddiv */
740 1, /* prefetch streams /*/
743 /* Instruction costs on PPCE500MC processors. */
745 struct processor_costs ppce500mc_cost = {
746 COSTS_N_INSNS (4), /* mulsi */
747 COSTS_N_INSNS (4), /* mulsi_const */
748 COSTS_N_INSNS (4), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (14), /* divsi */
751 COSTS_N_INSNS (14), /* divdi */
752 COSTS_N_INSNS (8), /* fp */
753 COSTS_N_INSNS (10), /* dmul */
754 COSTS_N_INSNS (36), /* sdiv */
755 COSTS_N_INSNS (66), /* ddiv */
756 64, /* cache line size */
759 1, /* prefetch streams /*/
762 /* Instruction costs on PPCE500MC64 processors. */
764 struct processor_costs ppce500mc64_cost = {
765 COSTS_N_INSNS (4), /* mulsi */
766 COSTS_N_INSNS (4), /* mulsi_const */
767 COSTS_N_INSNS (4), /* mulsi_const9 */
768 COSTS_N_INSNS (4), /* muldi */
769 COSTS_N_INSNS (14), /* divsi */
770 COSTS_N_INSNS (14), /* divdi */
771 COSTS_N_INSNS (4), /* fp */
772 COSTS_N_INSNS (10), /* dmul */
773 COSTS_N_INSNS (36), /* sdiv */
774 COSTS_N_INSNS (66), /* ddiv */
775 64, /* cache line size */
778 1, /* prefetch streams /*/
781 /* Instruction costs on POWER4 and POWER5 processors. */
783 struct processor_costs power4_cost = {
784 COSTS_N_INSNS (3), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (4), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (17), /* sdiv */
793 COSTS_N_INSNS (17), /* ddiv */
794 128, /* cache line size */
797 8, /* prefetch streams /*/
800 /* Instruction costs on POWER6 processors. */
802 struct processor_costs power6_cost = {
803 COSTS_N_INSNS (8), /* mulsi */
804 COSTS_N_INSNS (8), /* mulsi_const */
805 COSTS_N_INSNS (8), /* mulsi_const9 */
806 COSTS_N_INSNS (8), /* muldi */
807 COSTS_N_INSNS (22), /* divsi */
808 COSTS_N_INSNS (28), /* divdi */
809 COSTS_N_INSNS (3), /* fp */
810 COSTS_N_INSNS (3), /* dmul */
811 COSTS_N_INSNS (13), /* sdiv */
812 COSTS_N_INSNS (16), /* ddiv */
813 128, /* cache line size */
816 16, /* prefetch streams */
819 /* Instruction costs on POWER7 processors. */
821 struct processor_costs power7_cost = {
822 COSTS_N_INSNS (2), /* mulsi */
823 COSTS_N_INSNS (2), /* mulsi_const */
824 COSTS_N_INSNS (2), /* mulsi_const9 */
825 COSTS_N_INSNS (2), /* muldi */
826 COSTS_N_INSNS (18), /* divsi */
827 COSTS_N_INSNS (34), /* divdi */
828 COSTS_N_INSNS (3), /* fp */
829 COSTS_N_INSNS (3), /* dmul */
830 COSTS_N_INSNS (13), /* sdiv */
831 COSTS_N_INSNS (16), /* ddiv */
832 128, /* cache line size */
835 12, /* prefetch streams */
838 /* Instruction costs on POWER A2 processors. */
840 struct processor_costs ppca2_cost = {
841 COSTS_N_INSNS (16), /* mulsi */
842 COSTS_N_INSNS (16), /* mulsi_const */
843 COSTS_N_INSNS (16), /* mulsi_const9 */
844 COSTS_N_INSNS (16), /* muldi */
845 COSTS_N_INSNS (22), /* divsi */
846 COSTS_N_INSNS (28), /* divdi */
847 COSTS_N_INSNS (3), /* fp */
848 COSTS_N_INSNS (3), /* dmul */
849 COSTS_N_INSNS (59), /* sdiv */
850 COSTS_N_INSNS (72), /* ddiv */
854 16, /* prefetch streams */
858 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
859 #undef RS6000_BUILTIN
860 #undef RS6000_BUILTIN_EQUATE
861 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
862 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
864 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
866 #include "rs6000-builtin.def"
869 #undef RS6000_BUILTIN
870 #undef RS6000_BUILTIN_EQUATE
873 static bool rs6000_function_ok_for_sibcall (tree, tree);
874 static const char *rs6000_invalid_within_doloop (const_rtx);
875 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
876 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
877 static rtx rs6000_generate_compare (rtx, enum machine_mode);
878 static void rs6000_emit_stack_tie (void);
879 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
880 static bool spe_func_has_64bit_regs_p (void);
881 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
883 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
884 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
885 static unsigned rs6000_hash_constant (rtx);
886 static unsigned toc_hash_function (const void *);
887 static int toc_hash_eq (const void *, const void *);
888 static bool reg_offset_addressing_ok_p (enum machine_mode);
889 static bool virtual_stack_registers_memory_p (rtx);
890 static bool constant_pool_expr_p (rtx);
891 static bool legitimate_small_data_p (enum machine_mode, rtx);
892 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
893 static struct machine_function * rs6000_init_machine_status (void);
894 static bool rs6000_assemble_integer (rtx, unsigned int, int);
895 static bool no_global_regs_above (int, bool);
896 #ifdef HAVE_GAS_HIDDEN
897 static void rs6000_assemble_visibility (tree, int);
899 static int rs6000_ra_ever_killed (void);
900 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
901 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
902 static bool rs6000_ms_bitfield_layout_p (const_tree);
903 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
904 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
905 static const char *rs6000_mangle_type (const_tree);
906 static void rs6000_set_default_type_attributes (tree);
907 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
908 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
909 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
910 enum machine_mode, bool, bool, bool);
911 static bool rs6000_reg_live_or_pic_offset_p (int);
912 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
913 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
914 static void rs6000_restore_saved_cr (rtx, int);
915 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
916 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
917 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
919 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
920 static bool rs6000_return_in_memory (const_tree, const_tree);
921 static rtx rs6000_function_value (const_tree, const_tree, bool);
922 static void rs6000_file_start (void);
924 static int rs6000_elf_reloc_rw_mask (void);
925 static void rs6000_elf_asm_out_constructor (rtx, int);
926 static void rs6000_elf_asm_out_destructor (rtx, int);
927 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
928 static void rs6000_elf_asm_init_sections (void);
929 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
930 unsigned HOST_WIDE_INT);
931 static void rs6000_elf_encode_section_info (tree, rtx, int)
934 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
935 static void rs6000_alloc_sdmode_stack_slot (void);
936 static void rs6000_instantiate_decls (void);
938 static void rs6000_xcoff_asm_output_anchor (rtx);
939 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
940 static void rs6000_xcoff_asm_init_sections (void);
941 static int rs6000_xcoff_reloc_rw_mask (void);
942 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
943 static section *rs6000_xcoff_select_section (tree, int,
944 unsigned HOST_WIDE_INT);
945 static void rs6000_xcoff_unique_section (tree, int);
946 static section *rs6000_xcoff_select_rtx_section
947 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
948 static const char * rs6000_xcoff_strip_name_encoding (const char *);
949 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
950 static void rs6000_xcoff_file_start (void);
951 static void rs6000_xcoff_file_end (void);
953 static int rs6000_variable_issue (FILE *, int, rtx, int);
954 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
955 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
956 static int rs6000_debug_address_cost (rtx, bool);
957 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
958 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
959 static void rs6000_sched_init (FILE *, int, int);
960 static bool is_microcoded_insn (rtx);
961 static bool is_nonpipeline_insn (rtx);
962 static bool is_cracked_insn (rtx);
963 static bool is_branch_slot_insn (rtx);
964 static bool is_load_insn (rtx);
965 static rtx get_store_dest (rtx pat);
966 static bool is_store_insn (rtx);
967 static bool set_to_load_agen (rtx,rtx);
968 static bool adjacent_mem_locations (rtx,rtx);
969 static int rs6000_adjust_priority (rtx, int);
970 static int rs6000_issue_rate (void);
971 static bool rs6000_is_costly_dependence (dep_t, int, int);
972 static rtx get_next_active_insn (rtx, rtx);
973 static bool insn_terminates_group_p (rtx , enum group_termination);
974 static bool insn_must_be_first_in_group (rtx);
975 static bool insn_must_be_last_in_group (rtx);
976 static bool is_costly_group (rtx *, rtx);
977 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
978 static int redefine_groups (FILE *, int, rtx, rtx);
979 static int pad_groups (FILE *, int, rtx, rtx);
980 static void rs6000_sched_finish (FILE *, int);
981 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
982 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
983 static int rs6000_use_sched_lookahead (void);
984 static int rs6000_use_sched_lookahead_guard (rtx);
985 static void * rs6000_alloc_sched_context (void);
986 static void rs6000_init_sched_context (void *, bool);
987 static void rs6000_set_sched_context (void *);
988 static void rs6000_free_sched_context (void *);
989 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
990 static tree rs6000_builtin_mask_for_load (void);
991 static tree rs6000_builtin_mul_widen_even (tree);
992 static tree rs6000_builtin_mul_widen_odd (tree);
993 static tree rs6000_builtin_conversion (unsigned int, tree);
994 static tree rs6000_builtin_vec_perm (tree, tree *);
995 static bool rs6000_builtin_support_vector_misalignment (enum
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 bool rs6000_handle_option (size_t, const char *, int);
1048 static void rs6000_parse_tls_size_option (void);
1049 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
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 (CUMULATIVE_ARGS *,
1070 enum machine_mode, tree);
1071 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1073 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1074 tree, HOST_WIDE_INT);
1075 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1078 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1079 const_tree, HOST_WIDE_INT,
1081 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1082 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1083 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1084 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1085 enum machine_mode, tree,
1087 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1089 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1091 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1093 static void macho_branch_islands (void);
1094 static int no_previous_def (tree function_name);
1095 static tree get_prev_label (tree function_name);
1096 static void rs6000_darwin_file_start (void);
1099 static tree rs6000_build_builtin_va_list (void);
1100 static void rs6000_va_start (tree, rtx);
1101 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1102 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1103 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1104 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1105 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1106 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1108 static tree rs6000_stack_protect_fail (void);
1110 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1113 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1116 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1118 = rs6000_legitimize_reload_address;
1120 static bool rs6000_mode_dependent_address (rtx);
1121 static bool rs6000_debug_mode_dependent_address (rtx);
1122 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1123 = rs6000_mode_dependent_address;
1125 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1126 enum machine_mode, rtx);
1127 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1130 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1131 enum machine_mode, rtx)
1132 = rs6000_secondary_reload_class;
1134 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1135 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1137 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1138 = rs6000_preferred_reload_class;
1140 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1143 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1147 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1149 = rs6000_secondary_memory_needed;
1151 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1154 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1158 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1161 = rs6000_cannot_change_mode_class;
1163 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1165 struct secondary_reload_info *);
1167 static const enum reg_class *rs6000_ira_cover_classes (void);
1169 const int INSN_NOT_AVAILABLE = -1;
1170 static enum machine_mode rs6000_eh_return_filter_mode (void);
1171 static bool rs6000_can_eliminate (const int, const int);
1172 static void rs6000_trampoline_init (rtx, tree, rtx);
1174 /* Hash table stuff for keeping track of TOC entries. */
1176 struct GTY(()) toc_hash_struct
1178 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1179 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1181 enum machine_mode key_mode;
1185 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1187 /* Hash table to keep track of the argument types for builtin functions. */
1189 struct GTY(()) builtin_hash_struct
1192 enum machine_mode mode[4]; /* return value + 3 arguments. */
1193 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1196 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1198 /* Default register names. */
1199 char rs6000_reg_names[][8] =
1201 "0", "1", "2", "3", "4", "5", "6", "7",
1202 "8", "9", "10", "11", "12", "13", "14", "15",
1203 "16", "17", "18", "19", "20", "21", "22", "23",
1204 "24", "25", "26", "27", "28", "29", "30", "31",
1205 "0", "1", "2", "3", "4", "5", "6", "7",
1206 "8", "9", "10", "11", "12", "13", "14", "15",
1207 "16", "17", "18", "19", "20", "21", "22", "23",
1208 "24", "25", "26", "27", "28", "29", "30", "31",
1209 "mq", "lr", "ctr","ap",
1210 "0", "1", "2", "3", "4", "5", "6", "7",
1212 /* AltiVec registers. */
1213 "0", "1", "2", "3", "4", "5", "6", "7",
1214 "8", "9", "10", "11", "12", "13", "14", "15",
1215 "16", "17", "18", "19", "20", "21", "22", "23",
1216 "24", "25", "26", "27", "28", "29", "30", "31",
1218 /* SPE registers. */
1219 "spe_acc", "spefscr",
1220 /* Soft frame pointer. */
1224 #ifdef TARGET_REGNAMES
1225 static const char alt_reg_names[][8] =
1227 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1228 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1229 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1230 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1231 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1232 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1233 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1234 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1235 "mq", "lr", "ctr", "ap",
1236 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1238 /* AltiVec registers. */
1239 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1240 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1241 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1242 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1244 /* SPE registers. */
1245 "spe_acc", "spefscr",
1246 /* Soft frame pointer. */
1251 /* Table of valid machine attributes. */
1253 static const struct attribute_spec rs6000_attribute_table[] =
1255 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1256 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1257 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1258 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1259 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1260 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1261 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1262 SUBTARGET_ATTRIBUTE_TABLE,
1264 { NULL, 0, 0, false, false, false, NULL }
1267 #ifndef MASK_STRICT_ALIGN
1268 #define MASK_STRICT_ALIGN 0
1270 #ifndef TARGET_PROFILE_KERNEL
1271 #define TARGET_PROFILE_KERNEL 0
1272 #define SET_PROFILE_KERNEL(N)
1274 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1277 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1278 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1280 /* Initialize the GCC target structure. */
1281 #undef TARGET_ATTRIBUTE_TABLE
1282 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1283 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1284 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1286 #undef TARGET_ASM_ALIGNED_DI_OP
1287 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1289 /* Default unaligned ops are only provided for ELF. Find the ops needed
1290 for non-ELF systems. */
1291 #ifndef OBJECT_FORMAT_ELF
1293 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1295 #undef TARGET_ASM_UNALIGNED_HI_OP
1296 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1297 #undef TARGET_ASM_UNALIGNED_SI_OP
1298 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1299 #undef TARGET_ASM_UNALIGNED_DI_OP
1300 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1303 #undef TARGET_ASM_UNALIGNED_HI_OP
1304 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1305 #undef TARGET_ASM_UNALIGNED_SI_OP
1306 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1307 #undef TARGET_ASM_UNALIGNED_DI_OP
1308 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1309 #undef TARGET_ASM_ALIGNED_DI_OP
1310 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1314 /* This hook deals with fixups for relocatable code and DI-mode objects
1316 #undef TARGET_ASM_INTEGER
1317 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1319 #ifdef HAVE_GAS_HIDDEN
1320 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1321 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1324 #undef TARGET_HAVE_TLS
1325 #define TARGET_HAVE_TLS HAVE_AS_TLS
1327 #undef TARGET_CANNOT_FORCE_CONST_MEM
1328 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1330 #undef TARGET_DELEGITIMIZE_ADDRESS
1331 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1333 #undef TARGET_ASM_FUNCTION_PROLOGUE
1334 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1335 #undef TARGET_ASM_FUNCTION_EPILOGUE
1336 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1338 #undef TARGET_LEGITIMIZE_ADDRESS
1339 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1341 #undef TARGET_SCHED_VARIABLE_ISSUE
1342 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1344 #undef TARGET_SCHED_ISSUE_RATE
1345 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1346 #undef TARGET_SCHED_ADJUST_COST
1347 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1348 #undef TARGET_SCHED_ADJUST_PRIORITY
1349 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1350 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1351 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1352 #undef TARGET_SCHED_INIT
1353 #define TARGET_SCHED_INIT rs6000_sched_init
1354 #undef TARGET_SCHED_FINISH
1355 #define TARGET_SCHED_FINISH rs6000_sched_finish
1356 #undef TARGET_SCHED_REORDER
1357 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1358 #undef TARGET_SCHED_REORDER2
1359 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1361 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1362 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1364 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1365 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1367 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1368 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1369 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1370 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1371 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1372 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1373 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1374 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1376 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1377 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1378 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1379 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1380 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1381 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1382 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1383 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1384 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1385 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1386 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1387 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1388 rs6000_builtin_support_vector_misalignment
1389 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1390 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1392 #undef TARGET_INIT_BUILTINS
1393 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1394 #undef TARGET_BUILTIN_DECL
1395 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1397 #undef TARGET_EXPAND_BUILTIN
1398 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1400 #undef TARGET_MANGLE_TYPE
1401 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1403 #undef TARGET_INIT_LIBFUNCS
1404 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1407 #undef TARGET_BINDS_LOCAL_P
1408 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1411 #undef TARGET_MS_BITFIELD_LAYOUT_P
1412 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1414 #undef TARGET_ASM_OUTPUT_MI_THUNK
1415 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1417 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1418 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1420 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1421 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1423 #undef TARGET_INVALID_WITHIN_DOLOOP
1424 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1426 #undef TARGET_RTX_COSTS
1427 #define TARGET_RTX_COSTS rs6000_rtx_costs
1428 #undef TARGET_ADDRESS_COST
1429 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1431 #undef TARGET_DWARF_REGISTER_SPAN
1432 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1434 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1435 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1437 /* On rs6000, function arguments are promoted, as are function return
1439 #undef TARGET_PROMOTE_FUNCTION_MODE
1440 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1442 #undef TARGET_RETURN_IN_MEMORY
1443 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1445 #undef TARGET_SETUP_INCOMING_VARARGS
1446 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1448 /* Always strict argument naming on rs6000. */
1449 #undef TARGET_STRICT_ARGUMENT_NAMING
1450 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1451 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1452 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1453 #undef TARGET_SPLIT_COMPLEX_ARG
1454 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1455 #undef TARGET_MUST_PASS_IN_STACK
1456 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1457 #undef TARGET_PASS_BY_REFERENCE
1458 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1459 #undef TARGET_ARG_PARTIAL_BYTES
1460 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1462 #undef TARGET_BUILD_BUILTIN_VA_LIST
1463 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1465 #undef TARGET_EXPAND_BUILTIN_VA_START
1466 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1468 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1469 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1471 #undef TARGET_EH_RETURN_FILTER_MODE
1472 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1474 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1475 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1477 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1478 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1480 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1481 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1483 #undef TARGET_HANDLE_OPTION
1484 #define TARGET_HANDLE_OPTION rs6000_handle_option
1486 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1487 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1488 rs6000_builtin_vectorized_function
1490 #undef TARGET_DEFAULT_TARGET_FLAGS
1491 #define TARGET_DEFAULT_TARGET_FLAGS \
1494 #undef TARGET_STACK_PROTECT_FAIL
1495 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1497 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1498 The PowerPC architecture requires only weak consistency among
1499 processors--that is, memory accesses between processors need not be
1500 sequentially consistent and memory accesses among processors can occur
1501 in any order. The ability to order memory accesses weakly provides
1502 opportunities for more efficient use of the system bus. Unless a
1503 dependency exists, the 604e allows read operations to precede store
1505 #undef TARGET_RELAXED_ORDERING
1506 #define TARGET_RELAXED_ORDERING true
1509 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1510 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1513 /* Use a 32-bit anchor range. This leads to sequences like:
1515 addis tmp,anchor,high
1518 where tmp itself acts as an anchor, and can be shared between
1519 accesses to the same 64k page. */
1520 #undef TARGET_MIN_ANCHOR_OFFSET
1521 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1522 #undef TARGET_MAX_ANCHOR_OFFSET
1523 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1524 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1525 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1527 #undef TARGET_BUILTIN_RECIPROCAL
1528 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1530 #undef TARGET_EXPAND_TO_RTL_HOOK
1531 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1533 #undef TARGET_INSTANTIATE_DECLS
1534 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1536 #undef TARGET_SECONDARY_RELOAD
1537 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1539 #undef TARGET_IRA_COVER_CLASSES
1540 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1542 #undef TARGET_LEGITIMATE_ADDRESS_P
1543 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1545 #undef TARGET_CAN_ELIMINATE
1546 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1548 #undef TARGET_TRAMPOLINE_INIT
1549 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1551 #undef TARGET_FUNCTION_VALUE
1552 #define TARGET_FUNCTION_VALUE rs6000_function_value
1554 struct gcc_target targetm = TARGET_INITIALIZER;
1556 /* Return number of consecutive hard regs needed starting at reg REGNO
1557 to hold something of mode MODE.
1558 This is ordinarily the length in words of a value of mode MODE
1559 but can be less for certain modes in special long registers.
1561 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1562 scalar instructions. The upper 32 bits are only available to the
1565 POWER and PowerPC GPRs hold 32 bits worth;
1566 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1569 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1571 unsigned HOST_WIDE_INT reg_size;
1573 if (FP_REGNO_P (regno))
1574 reg_size = (VECTOR_MEM_VSX_P (mode)
1575 ? UNITS_PER_VSX_WORD
1576 : UNITS_PER_FP_WORD);
1578 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1579 reg_size = UNITS_PER_SPE_WORD;
1581 else if (ALTIVEC_REGNO_P (regno))
1582 reg_size = UNITS_PER_ALTIVEC_WORD;
1584 /* The value returned for SCmode in the E500 double case is 2 for
1585 ABI compatibility; storing an SCmode value in a single register
1586 would require function_arg and rs6000_spe_function_arg to handle
1587 SCmode so as to pass the value correctly in a pair of
1589 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1590 && !DECIMAL_FLOAT_MODE_P (mode))
1591 reg_size = UNITS_PER_FP_WORD;
1594 reg_size = UNITS_PER_WORD;
1596 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1599 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1602 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1604 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1606 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1607 implementations. Don't allow an item to be split between a FP register
1608 and an Altivec register. */
1609 if (VECTOR_MEM_VSX_P (mode))
1611 if (FP_REGNO_P (regno))
1612 return FP_REGNO_P (last_regno);
1614 if (ALTIVEC_REGNO_P (regno))
1615 return ALTIVEC_REGNO_P (last_regno);
1618 /* The GPRs can hold any mode, but values bigger than one register
1619 cannot go past R31. */
1620 if (INT_REGNO_P (regno))
1621 return INT_REGNO_P (last_regno);
1623 /* The float registers (except for VSX vector modes) can only hold floating
1624 modes and DImode. This excludes the 32-bit decimal float mode for
1626 if (FP_REGNO_P (regno))
1628 if (SCALAR_FLOAT_MODE_P (mode)
1629 && (mode != TDmode || (regno % 2) == 0)
1630 && FP_REGNO_P (last_regno))
1633 if (GET_MODE_CLASS (mode) == MODE_INT
1634 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1637 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1638 && PAIRED_VECTOR_MODE (mode))
1644 /* The CR register can only hold CC modes. */
1645 if (CR_REGNO_P (regno))
1646 return GET_MODE_CLASS (mode) == MODE_CC;
1648 if (XER_REGNO_P (regno))
1649 return mode == PSImode;
1651 /* AltiVec only in AldyVec registers. */
1652 if (ALTIVEC_REGNO_P (regno))
1653 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1655 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1656 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1659 /* We cannot put TImode anywhere except general register and it must be able
1660 to fit within the register set. In the future, allow TImode in the
1661 Altivec or VSX registers. */
1663 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1666 /* Print interesting facts about registers. */
1668 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1672 for (r = first_regno; r <= last_regno; ++r)
1674 const char *comma = "";
1677 if (first_regno == last_regno)
1678 fprintf (stderr, "%s:\t", reg_name);
1680 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1683 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1684 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1688 fprintf (stderr, ",\n\t");
1693 if (rs6000_hard_regno_nregs[m][r] > 1)
1694 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1695 rs6000_hard_regno_nregs[m][r]);
1697 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1702 if (call_used_regs[r])
1706 fprintf (stderr, ",\n\t");
1711 len += fprintf (stderr, "%s%s", comma, "call-used");
1719 fprintf (stderr, ",\n\t");
1724 len += fprintf (stderr, "%s%s", comma, "fixed");
1730 fprintf (stderr, ",\n\t");
1734 fprintf (stderr, "%sregno = %d\n", comma, r);
1738 /* Print various interesting information with -mdebug=reg. */
1740 rs6000_debug_reg_global (void)
1742 const char *nl = (const char *)0;
1744 char costly_num[20];
1746 const char *costly_str;
1747 const char *nop_str;
1749 /* Map enum rs6000_vector to string. */
1750 static const char *rs6000_debug_vector_unit[] = {
1759 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1760 LAST_VIRTUAL_REGISTER);
1761 rs6000_debug_reg_print (0, 31, "gr");
1762 rs6000_debug_reg_print (32, 63, "fp");
1763 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1766 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1767 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1768 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1769 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1770 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1771 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1772 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1773 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1774 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1778 "d reg_class = %s\n"
1779 "f reg_class = %s\n"
1780 "v reg_class = %s\n"
1781 "wa reg_class = %s\n"
1782 "wd reg_class = %s\n"
1783 "wf reg_class = %s\n"
1784 "ws reg_class = %s\n\n",
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1789 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1790 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1791 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1793 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1794 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1797 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1799 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1800 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1806 switch (rs6000_sched_costly_dep)
1808 case max_dep_latency:
1809 costly_str = "max_dep_latency";
1813 costly_str = "no_dep_costly";
1816 case all_deps_costly:
1817 costly_str = "all_deps_costly";
1820 case true_store_to_load_dep_costly:
1821 costly_str = "true_store_to_load_dep_costly";
1824 case store_to_load_dep_costly:
1825 costly_str = "store_to_load_dep_costly";
1829 costly_str = costly_num;
1830 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1834 switch (rs6000_sched_insert_nops)
1836 case sched_finish_regroup_exact:
1837 nop_str = "sched_finish_regroup_exact";
1840 case sched_finish_pad_groups:
1841 nop_str = "sched_finish_pad_groups";
1844 case sched_finish_none:
1845 nop_str = "sched_finish_none";
1850 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1855 "always_hint = %s\n"
1856 "align_branch_targets = %s\n"
1857 "sched_restricted_insns_priority = %d\n"
1858 "sched_costly_dep = %s\n"
1859 "sched_insert_nops = %s\n\n",
1860 rs6000_always_hint ? "true" : "false",
1861 rs6000_align_branch_targets ? "true" : "false",
1862 (int)rs6000_sched_restricted_insns_priority,
1863 costly_str, nop_str);
1866 /* Initialize the various global tables that are based on register size. */
1868 rs6000_init_hard_regno_mode_ok (void)
1874 /* Precalculate REGNO_REG_CLASS. */
1875 rs6000_regno_regclass[0] = GENERAL_REGS;
1876 for (r = 1; r < 32; ++r)
1877 rs6000_regno_regclass[r] = BASE_REGS;
1879 for (r = 32; r < 64; ++r)
1880 rs6000_regno_regclass[r] = FLOAT_REGS;
1882 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1883 rs6000_regno_regclass[r] = NO_REGS;
1885 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1886 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1888 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1889 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1890 rs6000_regno_regclass[r] = CR_REGS;
1892 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1893 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1894 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1895 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1896 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1897 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1898 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1899 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1900 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1901 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1903 /* Precalculate vector information, this must be set up before the
1904 rs6000_hard_regno_nregs_internal below. */
1905 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1907 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1908 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1909 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1912 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1913 rs6000_constraints[c] = NO_REGS;
1915 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1916 believes it can use native alignment or still uses 128-bit alignment. */
1917 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1928 /* V2DF mode, VSX only. */
1931 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1932 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1933 rs6000_vector_align[V2DFmode] = align64;
1936 /* V4SF mode, either VSX or Altivec. */
1939 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1940 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1941 rs6000_vector_align[V4SFmode] = align32;
1943 else if (TARGET_ALTIVEC)
1945 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1946 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1947 rs6000_vector_align[V4SFmode] = align32;
1950 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1954 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1955 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1956 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1957 rs6000_vector_align[V4SImode] = align32;
1958 rs6000_vector_align[V8HImode] = align32;
1959 rs6000_vector_align[V16QImode] = align32;
1963 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1964 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1965 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1969 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1970 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1971 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1975 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1976 Altivec doesn't have 64-bit support. */
1979 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1980 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1981 rs6000_vector_align[V2DImode] = align64;
1984 /* DFmode, see if we want to use the VSX unit. */
1985 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1987 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1988 rs6000_vector_mem[DFmode]
1989 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1990 rs6000_vector_align[DFmode] = align64;
1993 /* TODO add SPE and paired floating point vector support. */
1995 /* Register class constaints for the constraints that depend on compile
1997 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1998 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2000 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2001 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2005 /* At present, we just use VSX_REGS, but we have different constraints
2006 based on the use, in case we want to fine tune the default register
2007 class used. wa = any VSX register, wf = register class to use for
2008 V4SF, wd = register class to use for V2DF, and ws = register classs to
2009 use for DF scalars. */
2010 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2011 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2012 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2013 if (TARGET_VSX_SCALAR_DOUBLE)
2014 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2018 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2020 /* Set up the reload helper functions. */
2021 if (TARGET_VSX || TARGET_ALTIVEC)
2025 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2026 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2027 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2028 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2029 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2030 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2031 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2032 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2033 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2034 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2035 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2036 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2040 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2041 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2042 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2043 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2044 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2045 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2046 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2047 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2048 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2049 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2050 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2051 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2055 /* Precalculate HARD_REGNO_NREGS. */
2056 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2057 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2058 rs6000_hard_regno_nregs[m][r]
2059 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2061 /* Precalculate HARD_REGNO_MODE_OK. */
2062 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2063 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2064 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2065 rs6000_hard_regno_mode_ok_p[m][r] = true;
2067 /* Precalculate CLASS_MAX_NREGS sizes. */
2068 for (c = 0; c < LIM_REG_CLASSES; ++c)
2072 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2073 reg_size = UNITS_PER_VSX_WORD;
2075 else if (c == ALTIVEC_REGS)
2076 reg_size = UNITS_PER_ALTIVEC_WORD;
2078 else if (c == FLOAT_REGS)
2079 reg_size = UNITS_PER_FP_WORD;
2082 reg_size = UNITS_PER_WORD;
2084 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2085 rs6000_class_max_nregs[m][c]
2086 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2089 if (TARGET_E500_DOUBLE)
2090 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2092 if (TARGET_DEBUG_REG)
2093 rs6000_debug_reg_global ();
2097 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2100 darwin_rs6000_override_options (void)
2102 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2104 rs6000_altivec_abi = 1;
2105 TARGET_ALTIVEC_VRSAVE = 1;
2106 if (DEFAULT_ABI == ABI_DARWIN)
2108 if (MACHO_DYNAMIC_NO_PIC_P)
2111 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2114 else if (flag_pic == 1)
2119 if (TARGET_64BIT && ! TARGET_POWERPC64)
2121 target_flags |= MASK_POWERPC64;
2122 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2126 rs6000_default_long_calls = 1;
2127 target_flags |= MASK_SOFT_FLOAT;
2130 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2132 if (!flag_mkernel && !flag_apple_kext
2134 && ! (target_flags_explicit & MASK_ALTIVEC))
2135 target_flags |= MASK_ALTIVEC;
2137 /* Unless the user (not the configurer) has explicitly overridden
2138 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2139 G4 unless targetting the kernel. */
2142 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2143 && ! (target_flags_explicit & MASK_ALTIVEC)
2144 && ! rs6000_select[1].string)
2146 target_flags |= MASK_ALTIVEC;
2151 /* If not otherwise specified by a target, make 'long double' equivalent to
2154 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2155 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2158 /* Override command line options. Mostly we process the processor
2159 type and sometimes adjust other TARGET_ options. */
2162 rs6000_override_options (const char *default_cpu)
2165 struct rs6000_cpu_select *ptr;
2168 /* Simplifications for entries below. */
2171 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2172 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2175 /* This table occasionally claims that a processor does not support
2176 a particular feature even though it does, but the feature is slower
2177 than the alternative. Thus, it shouldn't be relied on as a
2178 complete description of the processor's support.
2180 Please keep this list in order, and don't forget to update the
2181 documentation in invoke.texi when adding a new processor or
2185 const char *const name; /* Canonical processor name. */
2186 const enum processor_type processor; /* Processor type enum value. */
2187 const int target_enable; /* Target flags to enable. */
2188 } const processor_target_table[]
2189 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2190 {"403", PROCESSOR_PPC403,
2191 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2192 {"405", PROCESSOR_PPC405,
2193 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2194 {"405fp", PROCESSOR_PPC405,
2195 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2196 {"440", PROCESSOR_PPC440,
2197 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2198 {"440fp", PROCESSOR_PPC440,
2199 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2200 {"464", PROCESSOR_PPC440,
2201 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2202 {"464fp", PROCESSOR_PPC440,
2203 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2204 {"476", PROCESSOR_PPC476,
2205 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2206 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2207 {"476fp", PROCESSOR_PPC476,
2208 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2209 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2210 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2211 {"601", PROCESSOR_PPC601,
2212 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2213 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2215 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2216 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2217 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2218 {"620", PROCESSOR_PPC620,
2219 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2220 {"630", PROCESSOR_PPC630,
2221 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2222 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2223 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2224 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2225 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2226 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2227 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2228 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2229 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2231 /* 8548 has a dummy entry for now. */
2232 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2234 {"a2", PROCESSOR_PPCA2,
2235 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2236 | MASK_CMPB | MASK_NO_UPDATE },
2237 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2238 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2239 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2241 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2242 | MASK_PPC_GFXOPT | MASK_ISEL},
2243 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2244 {"970", PROCESSOR_POWER4,
2245 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2246 {"cell", PROCESSOR_CELL,
2247 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2248 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2249 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2250 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2251 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2252 {"G5", PROCESSOR_POWER4,
2253 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2254 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2255 {"power2", PROCESSOR_POWER,
2256 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2257 {"power3", PROCESSOR_PPC630,
2258 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2259 {"power4", PROCESSOR_POWER4,
2260 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2262 {"power5", PROCESSOR_POWER5,
2263 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2264 | MASK_MFCRF | MASK_POPCNTB},
2265 {"power5+", PROCESSOR_POWER5,
2266 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2267 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2268 {"power6", PROCESSOR_POWER6,
2269 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2270 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2271 {"power6x", PROCESSOR_POWER6,
2272 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2273 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2275 {"power7", PROCESSOR_POWER7,
2276 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2277 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2278 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2279 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2280 {"powerpc64", PROCESSOR_POWERPC64,
2281 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2282 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2283 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rios2", PROCESSOR_RIOS2,
2285 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2286 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2287 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2288 {"rs64", PROCESSOR_RS64A,
2289 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2292 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2294 /* Some OSs don't support saving the high part of 64-bit registers on
2295 context switch. Other OSs don't support saving Altivec registers.
2296 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2297 settings; if the user wants either, the user must explicitly specify
2298 them and we won't interfere with the user's specification. */
2301 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2302 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2303 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2304 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2305 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2306 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2309 /* Numerous experiment shows that IRA based loop pressure
2310 calculation works better for RTL loop invariant motion on targets
2311 with enough (>= 32) registers. It is an expensive optimization.
2312 So it is on only for peak performance. */
2314 flag_ira_loop_pressure = 1;
2316 /* Set the pointer size. */
2319 rs6000_pmode = (int)DImode;
2320 rs6000_pointer_size = 64;
2324 rs6000_pmode = (int)SImode;
2325 rs6000_pointer_size = 32;
2328 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2329 #ifdef OS_MISSING_POWERPC64
2330 if (OS_MISSING_POWERPC64)
2331 set_masks &= ~MASK_POWERPC64;
2333 #ifdef OS_MISSING_ALTIVEC
2334 if (OS_MISSING_ALTIVEC)
2335 set_masks &= ~MASK_ALTIVEC;
2338 /* Don't override by the processor default if given explicitly. */
2339 set_masks &= ~target_flags_explicit;
2341 /* Identify the processor type. */
2342 rs6000_select[0].string = default_cpu;
2343 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2345 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2347 ptr = &rs6000_select[i];
2348 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2350 for (j = 0; j < ptt_size; j++)
2351 if (! strcmp (ptr->string, processor_target_table[j].name))
2353 if (ptr->set_tune_p)
2354 rs6000_cpu = processor_target_table[j].processor;
2356 if (ptr->set_arch_p)
2358 target_flags &= ~set_masks;
2359 target_flags |= (processor_target_table[j].target_enable
2366 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2370 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2371 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2374 error ("AltiVec not supported in this target");
2376 error ("Spe not supported in this target");
2379 /* Disable Cell microcode if we are optimizing for the Cell
2380 and not optimizing for size. */
2381 if (rs6000_gen_cell_microcode == -1)
2382 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2385 /* If we are optimizing big endian systems for space and it's OK to
2386 use instructions that would be microcoded on the Cell, use the
2387 load/store multiple and string instructions. */
2388 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2389 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2391 /* Don't allow -mmultiple or -mstring on little endian systems
2392 unless the cpu is a 750, because the hardware doesn't support the
2393 instructions used in little endian mode, and causes an alignment
2394 trap. The 750 does not cause an alignment trap (except when the
2395 target is unaligned). */
2397 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2399 if (TARGET_MULTIPLE)
2401 target_flags &= ~MASK_MULTIPLE;
2402 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2403 warning (0, "-mmultiple is not supported on little endian systems");
2408 target_flags &= ~MASK_STRING;
2409 if ((target_flags_explicit & MASK_STRING) != 0)
2410 warning (0, "-mstring is not supported on little endian systems");
2414 /* Add some warnings for VSX. */
2417 const char *msg = NULL;
2418 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2419 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2421 if (target_flags_explicit & MASK_VSX)
2422 msg = N_("-mvsx requires hardware floating point");
2424 target_flags &= ~ MASK_VSX;
2426 else if (TARGET_PAIRED_FLOAT)
2427 msg = N_("-mvsx and -mpaired are incompatible");
2428 /* The hardware will allow VSX and little endian, but until we make sure
2429 things like vector select, etc. work don't allow VSX on little endian
2430 systems at this point. */
2431 else if (!BYTES_BIG_ENDIAN)
2432 msg = N_("-mvsx used with little endian code");
2433 else if (TARGET_AVOID_XFORM > 0)
2434 msg = N_("-mvsx needs indexed addressing");
2435 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2437 if (target_flags_explicit & MASK_VSX)
2438 msg = N_("-mvsx and -mno-altivec are incompatible");
2440 msg = N_("-mno-altivec disables vsx");
2446 target_flags &= ~ MASK_VSX;
2448 else if (TARGET_VSX && !TARGET_ALTIVEC)
2449 target_flags |= MASK_ALTIVEC;
2452 /* Set debug flags */
2453 if (rs6000_debug_name)
2455 if (! strcmp (rs6000_debug_name, "all"))
2456 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2457 = rs6000_debug_addr = rs6000_debug_cost = 1;
2458 else if (! strcmp (rs6000_debug_name, "stack"))
2459 rs6000_debug_stack = 1;
2460 else if (! strcmp (rs6000_debug_name, "arg"))
2461 rs6000_debug_arg = 1;
2462 else if (! strcmp (rs6000_debug_name, "reg"))
2463 rs6000_debug_reg = 1;
2464 else if (! strcmp (rs6000_debug_name, "addr"))
2465 rs6000_debug_addr = 1;
2466 else if (! strcmp (rs6000_debug_name, "cost"))
2467 rs6000_debug_cost = 1;
2469 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2471 /* If the appropriate debug option is enabled, replace the target hooks
2472 with debug versions that call the real version and then prints
2473 debugging information. */
2474 if (TARGET_DEBUG_COST)
2476 targetm.rtx_costs = rs6000_debug_rtx_costs;
2477 targetm.address_cost = rs6000_debug_address_cost;
2478 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2481 if (TARGET_DEBUG_ADDR)
2483 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2484 targetm.legitimize_address = rs6000_debug_legitimize_address;
2485 rs6000_secondary_reload_class_ptr
2486 = rs6000_debug_secondary_reload_class;
2487 rs6000_secondary_memory_needed_ptr
2488 = rs6000_debug_secondary_memory_needed;
2489 rs6000_cannot_change_mode_class_ptr
2490 = rs6000_debug_cannot_change_mode_class;
2491 rs6000_preferred_reload_class_ptr
2492 = rs6000_debug_preferred_reload_class;
2493 rs6000_legitimize_reload_address_ptr
2494 = rs6000_debug_legitimize_reload_address;
2495 rs6000_mode_dependent_address_ptr
2496 = rs6000_debug_mode_dependent_address;
2500 if (rs6000_traceback_name)
2502 if (! strncmp (rs6000_traceback_name, "full", 4))
2503 rs6000_traceback = traceback_full;
2504 else if (! strncmp (rs6000_traceback_name, "part", 4))
2505 rs6000_traceback = traceback_part;
2506 else if (! strncmp (rs6000_traceback_name, "no", 2))
2507 rs6000_traceback = traceback_none;
2509 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2510 rs6000_traceback_name);
2513 if (!rs6000_explicit_options.long_double)
2514 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2516 #ifndef POWERPC_LINUX
2517 if (!rs6000_explicit_options.ieee)
2518 rs6000_ieeequad = 1;
2521 /* Enable Altivec ABI for AIX -maltivec. */
2522 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2523 rs6000_altivec_abi = 1;
2525 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2526 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2527 be explicitly overridden in either case. */
2530 if (!rs6000_explicit_options.altivec_abi
2531 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2532 rs6000_altivec_abi = 1;
2534 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2535 if (!rs6000_explicit_options.vrsave)
2536 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2539 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2540 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2542 rs6000_darwin64_abi = 1;
2544 darwin_one_byte_bool = 1;
2546 /* Default to natural alignment, for better performance. */
2547 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2550 /* Place FP constants in the constant pool instead of TOC
2551 if section anchors enabled. */
2552 if (flag_section_anchors)
2553 TARGET_NO_FP_IN_TOC = 1;
2555 /* Handle -mtls-size option. */
2556 rs6000_parse_tls_size_option ();
2558 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2559 SUBTARGET_OVERRIDE_OPTIONS;
2561 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2562 SUBSUBTARGET_OVERRIDE_OPTIONS;
2564 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2565 SUB3TARGET_OVERRIDE_OPTIONS;
2568 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2569 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2571 /* The e500 and e500mc do not have string instructions, and we set
2572 MASK_STRING above when optimizing for size. */
2573 if ((target_flags & MASK_STRING) != 0)
2574 target_flags = target_flags & ~MASK_STRING;
2576 else if (rs6000_select[1].string != NULL)
2578 /* For the powerpc-eabispe configuration, we set all these by
2579 default, so let's unset them if we manually set another
2580 CPU that is not the E500. */
2581 if (!rs6000_explicit_options.spe_abi)
2583 if (!rs6000_explicit_options.spe)
2585 if (!rs6000_explicit_options.float_gprs)
2586 rs6000_float_gprs = 0;
2587 if (!(target_flags_explicit & MASK_ISEL))
2588 target_flags &= ~MASK_ISEL;
2591 /* Detect invalid option combinations with E500. */
2594 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2595 && rs6000_cpu != PROCESSOR_POWER5
2596 && rs6000_cpu != PROCESSOR_POWER6
2597 && rs6000_cpu != PROCESSOR_POWER7
2598 && rs6000_cpu != PROCESSOR_PPCA2
2599 && rs6000_cpu != PROCESSOR_CELL);
2600 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2601 || rs6000_cpu == PROCESSOR_POWER5
2602 || rs6000_cpu == PROCESSOR_POWER7);
2603 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2604 || rs6000_cpu == PROCESSOR_POWER5
2605 || rs6000_cpu == PROCESSOR_POWER6
2606 || rs6000_cpu == PROCESSOR_POWER7
2607 || rs6000_cpu == PROCESSOR_PPCE500MC
2608 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2610 /* Allow debug switches to override the above settings. */
2611 if (TARGET_ALWAYS_HINT > 0)
2612 rs6000_always_hint = TARGET_ALWAYS_HINT;
2614 if (TARGET_SCHED_GROUPS > 0)
2615 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2617 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2618 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2620 rs6000_sched_restricted_insns_priority
2621 = (rs6000_sched_groups ? 1 : 0);
2623 /* Handle -msched-costly-dep option. */
2624 rs6000_sched_costly_dep
2625 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2627 if (rs6000_sched_costly_dep_str)
2629 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2630 rs6000_sched_costly_dep = no_dep_costly;
2631 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2632 rs6000_sched_costly_dep = all_deps_costly;
2633 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2634 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2635 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2636 rs6000_sched_costly_dep = store_to_load_dep_costly;
2638 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2639 atoi (rs6000_sched_costly_dep_str));
2642 /* Handle -minsert-sched-nops option. */
2643 rs6000_sched_insert_nops
2644 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2646 if (rs6000_sched_insert_nops_str)
2648 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2649 rs6000_sched_insert_nops = sched_finish_none;
2650 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2651 rs6000_sched_insert_nops = sched_finish_pad_groups;
2652 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2653 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2655 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2656 atoi (rs6000_sched_insert_nops_str));
2659 #ifdef TARGET_REGNAMES
2660 /* If the user desires alternate register names, copy in the
2661 alternate names now. */
2662 if (TARGET_REGNAMES)
2663 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2666 /* Set aix_struct_return last, after the ABI is determined.
2667 If -maix-struct-return or -msvr4-struct-return was explicitly
2668 used, don't override with the ABI default. */
2669 if (!rs6000_explicit_options.aix_struct_ret)
2670 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2672 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2673 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2676 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2678 /* We can only guarantee the availability of DI pseudo-ops when
2679 assembling for 64-bit targets. */
2682 targetm.asm_out.aligned_op.di = NULL;
2683 targetm.asm_out.unaligned_op.di = NULL;
2686 /* Set branch target alignment, if not optimizing for size. */
2689 /* Cell wants to be aligned 8byte for dual issue. */
2690 if (rs6000_cpu == PROCESSOR_CELL)
2692 if (align_functions <= 0)
2693 align_functions = 8;
2694 if (align_jumps <= 0)
2696 if (align_loops <= 0)
2699 if (rs6000_align_branch_targets)
2701 if (align_functions <= 0)
2702 align_functions = 16;
2703 if (align_jumps <= 0)
2705 if (align_loops <= 0)
2708 if (align_jumps_max_skip <= 0)
2709 align_jumps_max_skip = 15;
2710 if (align_loops_max_skip <= 0)
2711 align_loops_max_skip = 15;
2714 /* Arrange to save and restore machine status around nested functions. */
2715 init_machine_status = rs6000_init_machine_status;
2717 /* We should always be splitting complex arguments, but we can't break
2718 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2719 if (DEFAULT_ABI != ABI_AIX)
2720 targetm.calls.split_complex_arg = NULL;
2722 /* Initialize rs6000_cost with the appropriate target costs. */
2724 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2728 case PROCESSOR_RIOS1:
2729 rs6000_cost = &rios1_cost;
2732 case PROCESSOR_RIOS2:
2733 rs6000_cost = &rios2_cost;
2736 case PROCESSOR_RS64A:
2737 rs6000_cost = &rs64a_cost;
2740 case PROCESSOR_MPCCORE:
2741 rs6000_cost = &mpccore_cost;
2744 case PROCESSOR_PPC403:
2745 rs6000_cost = &ppc403_cost;
2748 case PROCESSOR_PPC405:
2749 rs6000_cost = &ppc405_cost;
2752 case PROCESSOR_PPC440:
2753 rs6000_cost = &ppc440_cost;
2756 case PROCESSOR_PPC476:
2757 rs6000_cost = &ppc476_cost;
2760 case PROCESSOR_PPC601:
2761 rs6000_cost = &ppc601_cost;
2764 case PROCESSOR_PPC603:
2765 rs6000_cost = &ppc603_cost;
2768 case PROCESSOR_PPC604:
2769 rs6000_cost = &ppc604_cost;
2772 case PROCESSOR_PPC604e:
2773 rs6000_cost = &ppc604e_cost;
2776 case PROCESSOR_PPC620:
2777 rs6000_cost = &ppc620_cost;
2780 case PROCESSOR_PPC630:
2781 rs6000_cost = &ppc630_cost;
2784 case PROCESSOR_CELL:
2785 rs6000_cost = &ppccell_cost;
2788 case PROCESSOR_PPC750:
2789 case PROCESSOR_PPC7400:
2790 rs6000_cost = &ppc750_cost;
2793 case PROCESSOR_PPC7450:
2794 rs6000_cost = &ppc7450_cost;
2797 case PROCESSOR_PPC8540:
2798 rs6000_cost = &ppc8540_cost;
2801 case PROCESSOR_PPCE300C2:
2802 case PROCESSOR_PPCE300C3:
2803 rs6000_cost = &ppce300c2c3_cost;
2806 case PROCESSOR_PPCE500MC:
2807 rs6000_cost = &ppce500mc_cost;
2810 case PROCESSOR_PPCE500MC64:
2811 rs6000_cost = &ppce500mc64_cost;
2814 case PROCESSOR_POWER4:
2815 case PROCESSOR_POWER5:
2816 rs6000_cost = &power4_cost;
2819 case PROCESSOR_POWER6:
2820 rs6000_cost = &power6_cost;
2823 case PROCESSOR_POWER7:
2824 rs6000_cost = &power7_cost;
2827 case PROCESSOR_PPCA2:
2828 rs6000_cost = &ppca2_cost;
2835 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2836 set_param_value ("simultaneous-prefetches",
2837 rs6000_cost->simultaneous_prefetches);
2838 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2839 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2840 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2841 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2842 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2843 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2845 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2846 can be optimized to ap = __builtin_next_arg (0). */
2847 if (DEFAULT_ABI != ABI_V4)
2848 targetm.expand_builtin_va_start = NULL;
2850 /* Set up single/double float flags.
2851 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2852 then set both flags. */
2853 if (TARGET_HARD_FLOAT && TARGET_FPRS
2854 && rs6000_single_float == 0 && rs6000_double_float == 0)
2855 rs6000_single_float = rs6000_double_float = 1;
2857 /* Reset single and double FP flags if target is E500. */
2860 rs6000_single_float = rs6000_double_float = 0;
2861 if (TARGET_E500_SINGLE)
2862 rs6000_single_float = 1;
2863 if (TARGET_E500_DOUBLE)
2864 rs6000_single_float = rs6000_double_float = 1;
2867 /* If not explicitly specified via option, decide whether to generate indexed
2868 load/store instructions. */
2869 if (TARGET_AVOID_XFORM == -1)
2870 /* Avoid indexed addressing when targeting Power6 in order to avoid
2871 the DERAT mispredict penalty. */
2872 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2874 rs6000_init_hard_regno_mode_ok ();
2877 /* Implement targetm.vectorize.builtin_mask_for_load. */
2879 rs6000_builtin_mask_for_load (void)
2881 if (TARGET_ALTIVEC || TARGET_VSX)
2882 return altivec_builtin_mask_for_load;
2887 /* Implement targetm.vectorize.builtin_conversion.
2888 Returns a decl of a function that implements conversion of an integer vector
2889 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2890 side of the conversion.
2891 Return NULL_TREE if it is not available. */
2893 rs6000_builtin_conversion (unsigned int tcode, tree type)
2895 enum tree_code code = (enum tree_code) tcode;
2899 case FIX_TRUNC_EXPR:
2900 switch (TYPE_MODE (type))
2903 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2906 return TYPE_UNSIGNED (type)
2907 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2908 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2911 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2914 return TYPE_UNSIGNED (type)
2915 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2916 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2923 switch (TYPE_MODE (type))
2926 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2929 return TYPE_UNSIGNED (type)
2930 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2931 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2934 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2937 return TYPE_UNSIGNED (type)
2938 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2939 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2950 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2952 rs6000_builtin_mul_widen_even (tree type)
2954 if (!TARGET_ALTIVEC)
2957 switch (TYPE_MODE (type))
2960 return TYPE_UNSIGNED (type)
2961 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2962 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2965 return TYPE_UNSIGNED (type)
2966 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2967 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2973 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2975 rs6000_builtin_mul_widen_odd (tree type)
2977 if (!TARGET_ALTIVEC)
2980 switch (TYPE_MODE (type))
2983 return TYPE_UNSIGNED (type)
2984 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2985 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2988 return TYPE_UNSIGNED (type)
2989 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2990 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2997 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2998 after applying N number of iterations. This routine does not determine
2999 how may iterations are required to reach desired alignment. */
3002 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3009 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3012 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3022 /* Assuming that all other types are naturally aligned. CHECKME! */
3027 /* Return true if the vector misalignment factor is supported by the
3030 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3037 /* Return if movmisalign pattern is not supported for this mode. */
3038 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3042 if (misalignment == -1)
3044 /* misalignment factor is unknown at compile time but we know
3045 it's word aligned. */
3046 if (rs6000_vector_alignment_reachable (type, is_packed))
3050 /* VSX supports word-aligned vector. */
3051 if (misalignment % 4 == 0)
3057 /* Implement targetm.vectorize.builtin_vec_perm. */
3059 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3061 tree inner_type = TREE_TYPE (type);
3062 bool uns_p = TYPE_UNSIGNED (inner_type);
3065 *mask_element_type = unsigned_char_type_node;
3067 switch (TYPE_MODE (type))
3071 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3072 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3077 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3078 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3083 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3084 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3088 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3092 if (!TARGET_ALLOW_DF_PERMUTE)
3095 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3099 if (!TARGET_ALLOW_DF_PERMUTE)
3103 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3104 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3115 /* Handle generic options of the form -mfoo=yes/no.
3116 NAME is the option name.
3117 VALUE is the option value.
3118 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3119 whether the option value is 'yes' or 'no' respectively. */
3121 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3125 else if (!strcmp (value, "yes"))
3127 else if (!strcmp (value, "no"))
3130 error ("unknown -m%s= option specified: '%s'", name, value);
3133 /* Validate and record the size specified with the -mtls-size option. */
3136 rs6000_parse_tls_size_option (void)
3138 if (rs6000_tls_size_string == 0)
3140 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3141 rs6000_tls_size = 16;
3142 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3143 rs6000_tls_size = 32;
3144 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3145 rs6000_tls_size = 64;
3147 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3151 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3153 if (DEFAULT_ABI == ABI_DARWIN)
3154 /* The Darwin libraries never set errno, so we might as well
3155 avoid calling them when that's the only reason we would. */
3156 flag_errno_math = 0;
3158 /* Double growth factor to counter reduced min jump length. */
3159 set_param_value ("max-grow-copy-bb-insns", 16);
3161 /* Enable section anchors by default.
3162 Skip section anchors for Objective C and Objective C++
3163 until front-ends fixed. */
3164 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3165 flag_section_anchors = 2;
3168 static enum fpu_type_t
3169 rs6000_parse_fpu_option (const char *option)
3171 if (!strcmp("none", option)) return FPU_NONE;
3172 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3173 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3174 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3175 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3176 error("unknown value %s for -mfpu", option);
3180 /* Returns a function decl for a vectorized version of the builtin function
3181 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3182 if it is not available. */
3185 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3188 enum machine_mode in_mode, out_mode;
3191 if (TREE_CODE (type_out) != VECTOR_TYPE
3192 || TREE_CODE (type_in) != VECTOR_TYPE
3193 || !TARGET_VECTORIZE_BUILTINS)
3196 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3197 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3198 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3199 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3203 case BUILT_IN_COPYSIGN:
3204 if (VECTOR_UNIT_VSX_P (V2DFmode)
3205 && out_mode == DFmode && out_n == 2
3206 && in_mode == DFmode && in_n == 2)
3207 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3209 case BUILT_IN_COPYSIGNF:
3210 if (out_mode != SFmode || out_n != 4
3211 || in_mode != SFmode || in_n != 4)
3213 if (VECTOR_UNIT_VSX_P (V4SFmode))
3214 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3215 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3216 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3219 if (VECTOR_UNIT_VSX_P (V2DFmode)
3220 && out_mode == DFmode && out_n == 2
3221 && in_mode == DFmode && in_n == 2)
3222 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3224 case BUILT_IN_SQRTF:
3225 if (VECTOR_UNIT_VSX_P (V4SFmode)
3226 && out_mode == SFmode && out_n == 4
3227 && in_mode == SFmode && in_n == 4)
3228 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3231 if (VECTOR_UNIT_VSX_P (V2DFmode)
3232 && out_mode == DFmode && out_n == 2
3233 && in_mode == DFmode && in_n == 2)
3234 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3236 case BUILT_IN_CEILF:
3237 if (out_mode != SFmode || out_n != 4
3238 || in_mode != SFmode || in_n != 4)
3240 if (VECTOR_UNIT_VSX_P (V4SFmode))
3241 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3242 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3243 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3245 case BUILT_IN_FLOOR:
3246 if (VECTOR_UNIT_VSX_P (V2DFmode)
3247 && out_mode == DFmode && out_n == 2
3248 && in_mode == DFmode && in_n == 2)
3249 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3251 case BUILT_IN_FLOORF:
3252 if (out_mode != SFmode || out_n != 4
3253 || in_mode != SFmode || in_n != 4)
3255 if (VECTOR_UNIT_VSX_P (V4SFmode))
3256 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3257 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3258 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3260 case BUILT_IN_TRUNC:
3261 if (VECTOR_UNIT_VSX_P (V2DFmode)
3262 && out_mode == DFmode && out_n == 2
3263 && in_mode == DFmode && in_n == 2)
3264 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3266 case BUILT_IN_TRUNCF:
3267 if (out_mode != SFmode || out_n != 4
3268 || in_mode != SFmode || in_n != 4)
3270 if (VECTOR_UNIT_VSX_P (V4SFmode))
3271 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3272 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3273 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3275 case BUILT_IN_NEARBYINT:
3276 if (VECTOR_UNIT_VSX_P (V2DFmode)
3277 && flag_unsafe_math_optimizations
3278 && out_mode == DFmode && out_n == 2
3279 && in_mode == DFmode && in_n == 2)
3280 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3282 case BUILT_IN_NEARBYINTF:
3283 if (VECTOR_UNIT_VSX_P (V4SFmode)
3284 && flag_unsafe_math_optimizations
3285 && out_mode == SFmode && out_n == 4
3286 && in_mode == SFmode && in_n == 4)
3287 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3290 if (VECTOR_UNIT_VSX_P (V2DFmode)
3291 && !flag_trapping_math
3292 && out_mode == DFmode && out_n == 2
3293 && in_mode == DFmode && in_n == 2)
3294 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3296 case BUILT_IN_RINTF:
3297 if (VECTOR_UNIT_VSX_P (V4SFmode)
3298 && !flag_trapping_math
3299 && out_mode == SFmode && out_n == 4
3300 && in_mode == SFmode && in_n == 4)
3301 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3310 /* Implement TARGET_HANDLE_OPTION. */
3313 rs6000_handle_option (size_t code, const char *arg, int value)
3315 enum fpu_type_t fpu_type = FPU_NONE;
3321 target_flags &= ~(MASK_POWER | MASK_POWER2
3322 | MASK_MULTIPLE | MASK_STRING);
3323 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3324 | MASK_MULTIPLE | MASK_STRING);
3326 case OPT_mno_powerpc:
3327 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3328 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3329 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3330 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3333 target_flags &= ~MASK_MINIMAL_TOC;
3334 TARGET_NO_FP_IN_TOC = 0;
3335 TARGET_NO_SUM_IN_TOC = 0;
3336 target_flags_explicit |= MASK_MINIMAL_TOC;
3337 #ifdef TARGET_USES_SYSV4_OPT
3338 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3339 just the same as -mminimal-toc. */
3340 target_flags |= MASK_MINIMAL_TOC;
3341 target_flags_explicit |= MASK_MINIMAL_TOC;
3345 #ifdef TARGET_USES_SYSV4_OPT
3347 /* Make -mtoc behave like -mminimal-toc. */
3348 target_flags |= MASK_MINIMAL_TOC;
3349 target_flags_explicit |= MASK_MINIMAL_TOC;
3353 #ifdef TARGET_USES_AIX64_OPT
3358 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3359 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3360 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3363 #ifdef TARGET_USES_AIX64_OPT
3368 target_flags &= ~MASK_POWERPC64;
3369 target_flags_explicit |= MASK_POWERPC64;
3372 case OPT_minsert_sched_nops_:
3373 rs6000_sched_insert_nops_str = arg;
3376 case OPT_mminimal_toc:
3379 TARGET_NO_FP_IN_TOC = 0;
3380 TARGET_NO_SUM_IN_TOC = 0;
3387 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3388 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3395 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3396 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3400 case OPT_mpowerpc_gpopt:
3401 case OPT_mpowerpc_gfxopt:
3404 target_flags |= MASK_POWERPC;
3405 target_flags_explicit |= MASK_POWERPC;
3409 case OPT_maix_struct_return:
3410 case OPT_msvr4_struct_return:
3411 rs6000_explicit_options.aix_struct_ret = true;
3415 rs6000_explicit_options.vrsave = true;
3416 TARGET_ALTIVEC_VRSAVE = value;
3420 rs6000_explicit_options.vrsave = true;
3421 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3425 target_flags_explicit |= MASK_ISEL;
3427 rs6000_parse_yes_no_option ("isel", arg, &isel);
3429 target_flags |= MASK_ISEL;
3431 target_flags &= ~MASK_ISEL;
3435 rs6000_explicit_options.spe = true;
3440 rs6000_explicit_options.spe = true;
3441 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3445 rs6000_debug_name = arg;
3448 #ifdef TARGET_USES_SYSV4_OPT
3450 rs6000_abi_name = arg;
3454 rs6000_sdata_name = arg;
3457 case OPT_mtls_size_:
3458 rs6000_tls_size_string = arg;
3461 case OPT_mrelocatable:
3464 target_flags |= MASK_MINIMAL_TOC;
3465 target_flags_explicit |= MASK_MINIMAL_TOC;
3466 TARGET_NO_FP_IN_TOC = 1;
3470 case OPT_mrelocatable_lib:
3473 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3474 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3475 TARGET_NO_FP_IN_TOC = 1;
3479 target_flags &= ~MASK_RELOCATABLE;
3480 target_flags_explicit |= MASK_RELOCATABLE;
3486 if (!strcmp (arg, "altivec"))
3488 rs6000_explicit_options.altivec_abi = true;
3489 rs6000_altivec_abi = 1;
3491 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3494 else if (! strcmp (arg, "no-altivec"))
3496 rs6000_explicit_options.altivec_abi = true;
3497 rs6000_altivec_abi = 0;
3499 else if (! strcmp (arg, "spe"))
3501 rs6000_explicit_options.spe_abi = true;
3503 rs6000_altivec_abi = 0;
3504 if (!TARGET_SPE_ABI)
3505 error ("not configured for ABI: '%s'", arg);
3507 else if (! strcmp (arg, "no-spe"))
3509 rs6000_explicit_options.spe_abi = true;
3513 /* These are here for testing during development only, do not
3514 document in the manual please. */
3515 else if (! strcmp (arg, "d64"))
3517 rs6000_darwin64_abi = 1;
3518 warning (0, "Using darwin64 ABI");
3520 else if (! strcmp (arg, "d32"))
3522 rs6000_darwin64_abi = 0;
3523 warning (0, "Using old darwin ABI");
3526 else if (! strcmp (arg, "ibmlongdouble"))
3528 rs6000_explicit_options.ieee = true;
3529 rs6000_ieeequad = 0;
3530 warning (0, "Using IBM extended precision long double");
3532 else if (! strcmp (arg, "ieeelongdouble"))
3534 rs6000_explicit_options.ieee = true;
3535 rs6000_ieeequad = 1;
3536 warning (0, "Using IEEE extended precision long double");
3541 error ("unknown ABI specified: '%s'", arg);
3547 rs6000_select[1].string = arg;
3551 rs6000_select[2].string = arg;
3554 case OPT_mtraceback_:
3555 rs6000_traceback_name = arg;
3558 case OPT_mfloat_gprs_:
3559 rs6000_explicit_options.float_gprs = true;
3560 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3561 rs6000_float_gprs = 1;
3562 else if (! strcmp (arg, "double"))
3563 rs6000_float_gprs = 2;
3564 else if (! strcmp (arg, "no"))
3565 rs6000_float_gprs = 0;
3568 error ("invalid option for -mfloat-gprs: '%s'", arg);
3573 case OPT_mlong_double_:
3574 rs6000_explicit_options.long_double = true;
3575 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3576 if (value != 64 && value != 128)
3578 error ("Unknown switch -mlong-double-%s", arg);
3579 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3583 rs6000_long_double_type_size = value;
3586 case OPT_msched_costly_dep_:
3587 rs6000_sched_costly_dep_str = arg;
3591 rs6000_explicit_options.alignment = true;
3592 if (! strcmp (arg, "power"))
3594 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3595 some C library functions, so warn about it. The flag may be
3596 useful for performance studies from time to time though, so
3597 don't disable it entirely. */
3598 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3599 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3600 " it is incompatible with the installed C and C++ libraries");
3601 rs6000_alignment_flags = MASK_ALIGN_POWER;
3603 else if (! strcmp (arg, "natural"))
3604 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3607 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3612 case OPT_msingle_float:
3613 if (!TARGET_SINGLE_FPU)
3614 warning (0, "-msingle-float option equivalent to -mhard-float");
3615 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3616 rs6000_double_float = 0;
3617 target_flags &= ~MASK_SOFT_FLOAT;
3618 target_flags_explicit |= MASK_SOFT_FLOAT;
3621 case OPT_mdouble_float:
3622 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3623 rs6000_single_float = 1;
3624 target_flags &= ~MASK_SOFT_FLOAT;
3625 target_flags_explicit |= MASK_SOFT_FLOAT;
3628 case OPT_msimple_fpu:
3629 if (!TARGET_SINGLE_FPU)
3630 warning (0, "-msimple-fpu option ignored");
3633 case OPT_mhard_float:
3634 /* -mhard_float implies -msingle-float and -mdouble-float. */
3635 rs6000_single_float = rs6000_double_float = 1;
3638 case OPT_msoft_float:
3639 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3640 rs6000_single_float = rs6000_double_float = 0;
3644 fpu_type = rs6000_parse_fpu_option(arg);
3645 if (fpu_type != FPU_NONE)
3646 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3648 target_flags &= ~MASK_SOFT_FLOAT;
3649 target_flags_explicit |= MASK_SOFT_FLOAT;
3650 rs6000_xilinx_fpu = 1;
3651 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3652 rs6000_single_float = 1;
3653 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3654 rs6000_single_float = rs6000_double_float = 1;
3655 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3656 rs6000_simple_fpu = 1;
3660 /* -mfpu=none is equivalent to -msoft-float */
3661 target_flags |= MASK_SOFT_FLOAT;
3662 target_flags_explicit |= MASK_SOFT_FLOAT;
3663 rs6000_single_float = rs6000_double_float = 0;
3670 /* Do anything needed at the start of the asm file. */
3673 rs6000_file_start (void)
3677 const char *start = buffer;
3678 struct rs6000_cpu_select *ptr;
3679 const char *default_cpu = TARGET_CPU_DEFAULT;
3680 FILE *file = asm_out_file;
3682 default_file_start ();
3684 #ifdef TARGET_BI_ARCH
3685 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3689 if (flag_verbose_asm)
3691 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3692 rs6000_select[0].string = default_cpu;
3694 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3696 ptr = &rs6000_select[i];
3697 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3699 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3704 if (PPC405_ERRATUM77)
3706 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3710 #ifdef USING_ELFOS_H
3711 switch (rs6000_sdata)
3713 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3714 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3715 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3716 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3719 if (rs6000_sdata && g_switch_value)
3721 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3731 #ifdef HAVE_AS_GNU_ATTRIBUTE
3732 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3734 fprintf (file, "\t.gnu_attribute 4, %d\n",
3735 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3736 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3738 fprintf (file, "\t.gnu_attribute 8, %d\n",
3739 (TARGET_ALTIVEC_ABI ? 2
3740 : TARGET_SPE_ABI ? 3
3742 fprintf (file, "\t.gnu_attribute 12, %d\n",
3743 aix_struct_return ? 2 : 1);
3748 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3750 switch_to_section (toc_section);
3751 switch_to_section (text_section);
3756 /* Return nonzero if this function is known to have a null epilogue. */
3759 direct_return (void)
3761 if (reload_completed)
3763 rs6000_stack_t *info = rs6000_stack_info ();
3765 if (info->first_gp_reg_save == 32
3766 && info->first_fp_reg_save == 64
3767 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3768 && ! info->lr_save_p
3769 && ! info->cr_save_p
3770 && info->vrsave_mask == 0
3778 /* Return the number of instructions it takes to form a constant in an
3779 integer register. */
3782 num_insns_constant_wide (HOST_WIDE_INT value)
3784 /* signed constant loadable with {cal|addi} */
3785 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3788 /* constant loadable with {cau|addis} */
3789 else if ((value & 0xffff) == 0
3790 && (value >> 31 == -1 || value >> 31 == 0))
3793 #if HOST_BITS_PER_WIDE_INT == 64
3794 else if (TARGET_POWERPC64)
3796 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3797 HOST_WIDE_INT high = value >> 31;
3799 if (high == 0 || high == -1)
3805 return num_insns_constant_wide (high) + 1;
3807 return num_insns_constant_wide (low) + 1;
3809 return (num_insns_constant_wide (high)
3810 + num_insns_constant_wide (low) + 1);
3819 num_insns_constant (rtx op, enum machine_mode mode)
3821 HOST_WIDE_INT low, high;
3823 switch (GET_CODE (op))
3826 #if HOST_BITS_PER_WIDE_INT == 64
3827 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3828 && mask64_operand (op, mode))
3832 return num_insns_constant_wide (INTVAL (op));
3835 if (mode == SFmode || mode == SDmode)
3840 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3841 if (DECIMAL_FLOAT_MODE_P (mode))
3842 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3844 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3845 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3848 if (mode == VOIDmode || mode == DImode)
3850 high = CONST_DOUBLE_HIGH (op);
3851 low = CONST_DOUBLE_LOW (op);
3858 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3859 if (DECIMAL_FLOAT_MODE_P (mode))
3860 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3862 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3863 high = l[WORDS_BIG_ENDIAN == 0];
3864 low = l[WORDS_BIG_ENDIAN != 0];
3868 return (num_insns_constant_wide (low)
3869 + num_insns_constant_wide (high));
3872 if ((high == 0 && low >= 0)
3873 || (high == -1 && low < 0))
3874 return num_insns_constant_wide (low);
3876 else if (mask64_operand (op, mode))
3880 return num_insns_constant_wide (high) + 1;
3883 return (num_insns_constant_wide (high)
3884 + num_insns_constant_wide (low) + 1);
3892 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3893 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3894 corresponding element of the vector, but for V4SFmode and V2SFmode,
3895 the corresponding "float" is interpreted as an SImode integer. */
3898 const_vector_elt_as_int (rtx op, unsigned int elt)
3900 rtx tmp = CONST_VECTOR_ELT (op, elt);
3901 if (GET_MODE (op) == V4SFmode
3902 || GET_MODE (op) == V2SFmode)
3903 tmp = gen_lowpart (SImode, tmp);
3904 return INTVAL (tmp);
3907 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3908 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3909 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3910 all items are set to the same value and contain COPIES replicas of the
3911 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3912 operand and the others are set to the value of the operand's msb. */
3915 vspltis_constant (rtx op, unsigned step, unsigned copies)
3917 enum machine_mode mode = GET_MODE (op);
3918 enum machine_mode inner = GET_MODE_INNER (mode);
3921 unsigned nunits = GET_MODE_NUNITS (mode);
3922 unsigned bitsize = GET_MODE_BITSIZE (inner);
3923 unsigned mask = GET_MODE_MASK (inner);
3925 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3926 HOST_WIDE_INT splat_val = val;
3927 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3929 /* Construct the value to be splatted, if possible. If not, return 0. */
3930 for (i = 2; i <= copies; i *= 2)
3932 HOST_WIDE_INT small_val;
3934 small_val = splat_val >> bitsize;
3936 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3938 splat_val = small_val;
3941 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3942 if (EASY_VECTOR_15 (splat_val))
3945 /* Also check if we can splat, and then add the result to itself. Do so if
3946 the value is positive, of if the splat instruction is using OP's mode;
3947 for splat_val < 0, the splat and the add should use the same mode. */
3948 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3949 && (splat_val >= 0 || (step == 1 && copies == 1)))
3952 /* Also check if are loading up the most significant bit which can be done by
3953 loading up -1 and shifting the value left by -1. */
3954 else if (EASY_VECTOR_MSB (splat_val, inner))
3960 /* Check if VAL is present in every STEP-th element, and the
3961 other elements are filled with its most significant bit. */
3962 for (i = 0; i < nunits - 1; ++i)
3964 HOST_WIDE_INT desired_val;
3965 if (((i + 1) & (step - 1)) == 0)
3968 desired_val = msb_val;
3970 if (desired_val != const_vector_elt_as_int (op, i))
3978 /* Return true if OP is of the given MODE and can be synthesized
3979 with a vspltisb, vspltish or vspltisw. */
3982 easy_altivec_constant (rtx op, enum machine_mode mode)
3984 unsigned step, copies;
3986 if (mode == VOIDmode)
3987 mode = GET_MODE (op);
3988 else if (mode != GET_MODE (op))
3991 /* Start with a vspltisw. */
3992 step = GET_MODE_NUNITS (mode) / 4;
3995 if (vspltis_constant (op, step, copies))
3998 /* Then try with a vspltish. */
4004 if (vspltis_constant (op, step, copies))
4007 /* And finally a vspltisb. */
4013 if (vspltis_constant (op, step, copies))
4019 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4020 result is OP. Abort if it is not possible. */
4023 gen_easy_altivec_constant (rtx op)
4025 enum machine_mode mode = GET_MODE (op);
4026 int nunits = GET_MODE_NUNITS (mode);
4027 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4028 unsigned step = nunits / 4;
4029 unsigned copies = 1;
4031 /* Start with a vspltisw. */
4032 if (vspltis_constant (op, step, copies))
4033 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4035 /* Then try with a vspltish. */
4041 if (vspltis_constant (op, step, copies))
4042 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4044 /* And finally a vspltisb. */
4050 if (vspltis_constant (op, step, copies))
4051 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4057 output_vec_const_move (rtx *operands)
4060 enum machine_mode mode;
4065 mode = GET_MODE (dest);
4067 if (TARGET_VSX && zero_constant (vec, mode))
4068 return "xxlxor %x0,%x0,%x0";
4073 if (zero_constant (vec, mode))
4074 return "vxor %0,%0,%0";
4076 splat_vec = gen_easy_altivec_constant (vec);
4077 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4078 operands[1] = XEXP (splat_vec, 0);
4079 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4082 switch (GET_MODE (splat_vec))
4085 return "vspltisw %0,%1";
4088 return "vspltish %0,%1";
4091 return "vspltisb %0,%1";
4098 gcc_assert (TARGET_SPE);
4100 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4101 pattern of V1DI, V4HI, and V2SF.
4103 FIXME: We should probably return # and add post reload
4104 splitters for these, but this way is so easy ;-). */
4105 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4106 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4107 operands[1] = CONST_VECTOR_ELT (vec, 0);
4108 operands[2] = CONST_VECTOR_ELT (vec, 1);
4110 return "li %0,%1\n\tevmergelo %0,%0,%0";
4112 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4115 /* Initialize TARGET of vector PAIRED to VALS. */
4118 paired_expand_vector_init (rtx target, rtx vals)
4120 enum machine_mode mode = GET_MODE (target);
4121 int n_elts = GET_MODE_NUNITS (mode);
4123 rtx x, new_rtx, tmp, constant_op, op1, op2;
4126 for (i = 0; i < n_elts; ++i)
4128 x = XVECEXP (vals, 0, i);
4129 if (!CONSTANT_P (x))
4134 /* Load from constant pool. */
4135 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4141 /* The vector is initialized only with non-constants. */
4142 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4143 XVECEXP (vals, 0, 1));
4145 emit_move_insn (target, new_rtx);
4149 /* One field is non-constant and the other one is a constant. Load the
4150 constant from the constant pool and use ps_merge instruction to
4151 construct the whole vector. */
4152 op1 = XVECEXP (vals, 0, 0);
4153 op2 = XVECEXP (vals, 0, 1);
4155 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4157 tmp = gen_reg_rtx (GET_MODE (constant_op));
4158 emit_move_insn (tmp, constant_op);
4160 if (CONSTANT_P (op1))
4161 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4163 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4165 emit_move_insn (target, new_rtx);
4169 paired_expand_vector_move (rtx operands[])
4171 rtx op0 = operands[0], op1 = operands[1];
4173 emit_move_insn (op0, op1);
4176 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4177 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4178 operands for the relation operation COND. This is a recursive
4182 paired_emit_vector_compare (enum rtx_code rcode,
4183 rtx dest, rtx op0, rtx op1,
4184 rtx cc_op0, rtx cc_op1)
4186 rtx tmp = gen_reg_rtx (V2SFmode);
4187 rtx tmp1, max, min, equal_zero;
4189 gcc_assert (TARGET_PAIRED_FLOAT);
4190 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4196 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4200 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4201 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4205 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4208 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4211 tmp1 = gen_reg_rtx (V2SFmode);
4212 max = gen_reg_rtx (V2SFmode);
4213 min = gen_reg_rtx (V2SFmode);
4214 equal_zero = gen_reg_rtx (V2SFmode);
4216 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4217 emit_insn (gen_selv2sf4
4218 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4219 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4220 emit_insn (gen_selv2sf4
4221 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4222 emit_insn (gen_subv2sf3 (tmp1, min, max));
4223 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4226 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4229 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4232 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4235 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4238 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4247 /* Emit vector conditional expression.
4248 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4249 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4252 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4253 rtx cond, rtx cc_op0, rtx cc_op1)
4255 enum rtx_code rcode = GET_CODE (cond);
4257 if (!TARGET_PAIRED_FLOAT)
4260 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4265 /* Initialize vector TARGET to VALS. */
4268 rs6000_expand_vector_init (rtx target, rtx vals)
4270 enum machine_mode mode = GET_MODE (target);
4271 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4272 int n_elts = GET_MODE_NUNITS (mode);
4273 int n_var = 0, one_var = -1;
4274 bool all_same = true, all_const_zero = true;
4278 for (i = 0; i < n_elts; ++i)
4280 x = XVECEXP (vals, 0, i);
4281 if (!CONSTANT_P (x))
4282 ++n_var, one_var = i;
4283 else if (x != CONST0_RTX (inner_mode))
4284 all_const_zero = false;
4286 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4292 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4293 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4294 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4296 /* Zero register. */
4297 emit_insn (gen_rtx_SET (VOIDmode, target,
4298 gen_rtx_XOR (mode, target, target)));
4301 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4303 /* Splat immediate. */
4304 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4309 /* Load from constant pool. */
4310 emit_move_insn (target, const_vec);
4315 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4316 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4320 rtx element = XVECEXP (vals, 0, 0);
4321 if (mode == V2DFmode)
4322 emit_insn (gen_vsx_splat_v2df (target, element));
4324 emit_insn (gen_vsx_splat_v2di (target, element));
4328 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4329 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4330 if (mode == V2DFmode)
4331 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4333 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4338 /* With single precision floating point on VSX, know that internally single
4339 precision is actually represented as a double, and either make 2 V2DF
4340 vectors, and convert these vectors to single precision, or do one
4341 conversion, and splat the result to the other elements. */
4342 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4346 rtx freg = gen_reg_rtx (V4SFmode);
4347 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4349 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4350 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4354 rtx dbl_even = gen_reg_rtx (V2DFmode);
4355 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4356 rtx flt_even = gen_reg_rtx (V4SFmode);
4357 rtx flt_odd = gen_reg_rtx (V4SFmode);
4359 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4360 copy_to_reg (XVECEXP (vals, 0, 0)),
4361 copy_to_reg (XVECEXP (vals, 0, 1))));
4362 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4363 copy_to_reg (XVECEXP (vals, 0, 2)),
4364 copy_to_reg (XVECEXP (vals, 0, 3))));
4365 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4366 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4367 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4372 /* Store value to stack temp. Load vector element. Splat. However, splat
4373 of 64-bit items is not supported on Altivec. */
4374 if (all_same && GET_MODE_SIZE (mode) <= 4)
4376 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4377 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4378 XVECEXP (vals, 0, 0));
4379 x = gen_rtx_UNSPEC (VOIDmode,
4380 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4381 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4383 gen_rtx_SET (VOIDmode,
4386 x = gen_rtx_VEC_SELECT (inner_mode, target,
4387 gen_rtx_PARALLEL (VOIDmode,
4388 gen_rtvec (1, const0_rtx)));
4389 emit_insn (gen_rtx_SET (VOIDmode, target,
4390 gen_rtx_VEC_DUPLICATE (mode, x)));
4394 /* One field is non-constant. Load constant then overwrite
4398 rtx copy = copy_rtx (vals);
4400 /* Load constant part of vector, substitute neighboring value for
4402 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4403 rs6000_expand_vector_init (target, copy);
4405 /* Insert variable. */
4406 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4410 /* Construct the vector in memory one field at a time
4411 and load the whole vector. */
4412 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4413 for (i = 0; i < n_elts; i++)
4414 emit_move_insn (adjust_address_nv (mem, inner_mode,
4415 i * GET_MODE_SIZE (inner_mode)),
4416 XVECEXP (vals, 0, i));
4417 emit_move_insn (target, mem);
4420 /* Set field ELT of TARGET to VAL. */
4423 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4425 enum machine_mode mode = GET_MODE (target);
4426 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4427 rtx reg = gen_reg_rtx (mode);
4429 int width = GET_MODE_SIZE (inner_mode);
4432 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4434 rtx (*set_func) (rtx, rtx, rtx, rtx)
4435 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4436 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4440 /* Load single variable value. */
4441 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4442 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4443 x = gen_rtx_UNSPEC (VOIDmode,
4444 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4445 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4447 gen_rtx_SET (VOIDmode,
4451 /* Linear sequence. */
4452 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4453 for (i = 0; i < 16; ++i)
4454 XVECEXP (mask, 0, i) = GEN_INT (i);
4456 /* Set permute mask to insert element into target. */
4457 for (i = 0; i < width; ++i)
4458 XVECEXP (mask, 0, elt*width + i)
4459 = GEN_INT (i + 0x10);
4460 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4461 x = gen_rtx_UNSPEC (mode,
4462 gen_rtvec (3, target, reg,
4463 force_reg (V16QImode, x)),
4465 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4468 /* Extract field ELT from VEC into TARGET. */
4471 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4473 enum machine_mode mode = GET_MODE (vec);
4474 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4477 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4479 rtx (*extract_func) (rtx, rtx, rtx)
4480 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4481 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4485 /* Allocate mode-sized buffer. */
4486 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4488 /* Add offset to field within buffer matching vector element. */
4489 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4491 /* Store single field into mode-sized buffer. */
4492 x = gen_rtx_UNSPEC (VOIDmode,
4493 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4494 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4496 gen_rtx_SET (VOIDmode,
4499 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4502 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4503 implement ANDing by the mask IN. */
4505 build_mask64_2_operands (rtx in, rtx *out)
4507 #if HOST_BITS_PER_WIDE_INT >= 64
4508 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4511 gcc_assert (GET_CODE (in) == CONST_INT);
4516 /* Assume c initially something like 0x00fff000000fffff. The idea
4517 is to rotate the word so that the middle ^^^^^^ group of zeros
4518 is at the MS end and can be cleared with an rldicl mask. We then
4519 rotate back and clear off the MS ^^ group of zeros with a
4521 c = ~c; /* c == 0xff000ffffff00000 */
4522 lsb = c & -c; /* lsb == 0x0000000000100000 */
4523 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4524 c = ~c; /* c == 0x00fff000000fffff */
4525 c &= -lsb; /* c == 0x00fff00000000000 */
4526 lsb = c & -c; /* lsb == 0x0000100000000000 */
4527 c = ~c; /* c == 0xff000fffffffffff */
4528 c &= -lsb; /* c == 0xff00000000000000 */
4530 while ((lsb >>= 1) != 0)
4531 shift++; /* shift == 44 on exit from loop */
4532 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4533 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4534 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4538 /* Assume c initially something like 0xff000f0000000000. The idea
4539 is to rotate the word so that the ^^^ middle group of zeros
4540 is at the LS end and can be cleared with an rldicr mask. We then
4541 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4543 lsb = c & -c; /* lsb == 0x0000010000000000 */
4544 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4545 c = ~c; /* c == 0x00fff0ffffffffff */
4546 c &= -lsb; /* c == 0x00fff00000000000 */
4547 lsb = c & -c; /* lsb == 0x0000100000000000 */
4548 c = ~c; /* c == 0xff000fffffffffff */
4549 c &= -lsb; /* c == 0xff00000000000000 */
4551 while ((lsb >>= 1) != 0)
4552 shift++; /* shift == 44 on exit from loop */
4553 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4554 m1 >>= shift; /* m1 == 0x0000000000000fff */
4555 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4558 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4559 masks will be all 1's. We are guaranteed more than one transition. */
4560 out[0] = GEN_INT (64 - shift);
4561 out[1] = GEN_INT (m1);
4562 out[2] = GEN_INT (shift);
4563 out[3] = GEN_INT (m2);
4571 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4574 invalid_e500_subreg (rtx op, enum machine_mode mode)
4576 if (TARGET_E500_DOUBLE)
4578 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4579 subreg:TI and reg:TF. Decimal float modes are like integer
4580 modes (only low part of each register used) for this
4582 if (GET_CODE (op) == SUBREG
4583 && (mode == SImode || mode == DImode || mode == TImode
4584 || mode == DDmode || mode == TDmode)
4585 && REG_P (SUBREG_REG (op))
4586 && (GET_MODE (SUBREG_REG (op)) == DFmode
4587 || GET_MODE (SUBREG_REG (op)) == TFmode))
4590 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4592 if (GET_CODE (op) == SUBREG
4593 && (mode == DFmode || mode == TFmode)
4594 && REG_P (SUBREG_REG (op))
4595 && (GET_MODE (SUBREG_REG (op)) == DImode
4596 || GET_MODE (SUBREG_REG (op)) == TImode
4597 || GET_MODE (SUBREG_REG (op)) == DDmode
4598 || GET_MODE (SUBREG_REG (op)) == TDmode))
4603 && GET_CODE (op) == SUBREG
4605 && REG_P (SUBREG_REG (op))
4606 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4612 /* AIX increases natural record alignment to doubleword if the first
4613 field is an FP double while the FP fields remain word aligned. */
4616 rs6000_special_round_type_align (tree type, unsigned int computed,
4617 unsigned int specified)
4619 unsigned int align = MAX (computed, specified);
4620 tree field = TYPE_FIELDS (type);
4622 /* Skip all non field decls */
4623 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4624 field = TREE_CHAIN (field);
4626 if (field != NULL && field != type)
4628 type = TREE_TYPE (field);
4629 while (TREE_CODE (type) == ARRAY_TYPE)
4630 type = TREE_TYPE (type);
4632 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4633 align = MAX (align, 64);
4639 /* Darwin increases record alignment to the natural alignment of
4643 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4644 unsigned int specified)
4646 unsigned int align = MAX (computed, specified);
4648 if (TYPE_PACKED (type))
4651 /* Find the first field, looking down into aggregates. */
4653 tree field = TYPE_FIELDS (type);
4654 /* Skip all non field decls */
4655 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4656 field = TREE_CHAIN (field);
4659 type = TREE_TYPE (field);
4660 while (TREE_CODE (type) == ARRAY_TYPE)
4661 type = TREE_TYPE (type);
4662 } while (AGGREGATE_TYPE_P (type));
4664 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4665 align = MAX (align, TYPE_ALIGN (type));
4670 /* Return 1 for an operand in small memory on V.4/eabi. */
4673 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4674 enum machine_mode mode ATTRIBUTE_UNUSED)
4679 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4682 if (DEFAULT_ABI != ABI_V4)
4685 /* Vector and float memory instructions have a limited offset on the
4686 SPE, so using a vector or float variable directly as an operand is
4689 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4692 if (GET_CODE (op) == SYMBOL_REF)
4695 else if (GET_CODE (op) != CONST
4696 || GET_CODE (XEXP (op, 0)) != PLUS
4697 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4698 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4703 rtx sum = XEXP (op, 0);
4704 HOST_WIDE_INT summand;
4706 /* We have to be careful here, because it is the referenced address
4707 that must be 32k from _SDA_BASE_, not just the symbol. */
4708 summand = INTVAL (XEXP (sum, 1));
4709 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4712 sym_ref = XEXP (sum, 0);
4715 return SYMBOL_REF_SMALL_P (sym_ref);
4721 /* Return true if either operand is a general purpose register. */
4724 gpr_or_gpr_p (rtx op0, rtx op1)
4726 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4727 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4731 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4734 reg_offset_addressing_ok_p (enum machine_mode mode)
4744 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4745 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4753 /* Paired vector modes. Only reg+reg addressing is valid. */
4754 if (TARGET_PAIRED_FLOAT)
4766 virtual_stack_registers_memory_p (rtx op)
4770 if (GET_CODE (op) == REG)
4771 regnum = REGNO (op);
4773 else if (GET_CODE (op) == PLUS
4774 && GET_CODE (XEXP (op, 0)) == REG
4775 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4776 regnum = REGNO (XEXP (op, 0));
4781 return (regnum >= FIRST_VIRTUAL_REGISTER
4782 && regnum <= LAST_VIRTUAL_REGISTER);
4786 constant_pool_expr_p (rtx op)
4790 split_const (op, &base, &offset);
4791 return (GET_CODE (base) == SYMBOL_REF
4792 && CONSTANT_POOL_ADDRESS_P (base)
4793 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4797 toc_relative_expr_p (rtx op)
4801 if (GET_CODE (op) != CONST)
4804 split_const (op, &base, &offset);
4805 return (GET_CODE (base) == UNSPEC
4806 && XINT (base, 1) == UNSPEC_TOCREL);
4810 legitimate_constant_pool_address_p (rtx x)
4813 && GET_CODE (x) == PLUS
4814 && GET_CODE (XEXP (x, 0)) == REG
4815 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4816 && toc_relative_expr_p (XEXP (x, 1)));
4820 legitimate_small_data_p (enum machine_mode mode, rtx x)
4822 return (DEFAULT_ABI == ABI_V4
4823 && !flag_pic && !TARGET_TOC
4824 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4825 && small_data_operand (x, mode));
4828 /* SPE offset addressing is limited to 5-bits worth of double words. */
4829 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4832 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4834 unsigned HOST_WIDE_INT offset, extra;
4836 if (GET_CODE (x) != PLUS)
4838 if (GET_CODE (XEXP (x, 0)) != REG)
4840 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4842 if (!reg_offset_addressing_ok_p (mode))
4843 return virtual_stack_registers_memory_p (x);
4844 if (legitimate_constant_pool_address_p (x))
4846 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4849 offset = INTVAL (XEXP (x, 1));
4857 /* SPE vector modes. */
4858 return SPE_CONST_OFFSET_OK (offset);
4861 if (TARGET_E500_DOUBLE)
4862 return SPE_CONST_OFFSET_OK (offset);
4864 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4866 if (VECTOR_MEM_VSX_P (DFmode))
4871 /* On e500v2, we may have:
4873 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4875 Which gets addressed with evldd instructions. */
4876 if (TARGET_E500_DOUBLE)
4877 return SPE_CONST_OFFSET_OK (offset);
4879 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4881 else if (offset & 3)
4886 if (TARGET_E500_DOUBLE)
4887 return (SPE_CONST_OFFSET_OK (offset)
4888 && SPE_CONST_OFFSET_OK (offset + 8));
4892 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4894 else if (offset & 3)
4905 return (offset < 0x10000) && (offset + extra < 0x10000);
4909 legitimate_indexed_address_p (rtx x, int strict)
4913 if (GET_CODE (x) != PLUS)
4919 /* Recognize the rtl generated by reload which we know will later be
4920 replaced with proper base and index regs. */
4922 && reload_in_progress
4923 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4927 return (REG_P (op0) && REG_P (op1)
4928 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4929 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4930 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4931 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4935 avoiding_indexed_address_p (enum machine_mode mode)
4937 /* Avoid indexed addressing for modes that have non-indexed
4938 load/store instruction forms. */
4939 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4943 legitimate_indirect_address_p (rtx x, int strict)
4945 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4949 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4951 if (!TARGET_MACHO || !flag_pic
4952 || mode != SImode || GET_CODE (x) != MEM)
4956 if (GET_CODE (x) != LO_SUM)
4958 if (GET_CODE (XEXP (x, 0)) != REG)
4960 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4964 return CONSTANT_P (x);
4968 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4970 if (GET_CODE (x) != LO_SUM)
4972 if (GET_CODE (XEXP (x, 0)) != REG)
4974 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4976 /* Restrict addressing for DI because of our SUBREG hackery. */
4977 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4978 || mode == DDmode || mode == TDmode
4983 if (TARGET_ELF || TARGET_MACHO)
4985 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4989 if (GET_MODE_NUNITS (mode) != 1)
4991 if (GET_MODE_BITSIZE (mode) > 64
4992 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4993 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4994 && (mode == DFmode || mode == DDmode))))
4997 return CONSTANT_P (x);
5004 /* Try machine-dependent ways of modifying an illegitimate address
5005 to be legitimate. If we find one, return the new, valid address.
5006 This is used from only one place: `memory_address' in explow.c.
5008 OLDX is the address as it was before break_out_memory_refs was
5009 called. In some cases it is useful to look at this to decide what
5012 It is always safe for this function to do nothing. It exists to
5013 recognize opportunities to optimize the output.
5015 On RS/6000, first check for the sum of a register with a constant
5016 integer that is out of range. If so, generate code to add the
5017 constant with the low-order 16 bits masked to the register and force
5018 this result into another register (this can be done with `cau').
5019 Then generate an address of REG+(CONST&0xffff), allowing for the
5020 possibility of bit 16 being a one.
5022 Then check for the sum of a register and something not constant, try to
5023 load the other things into a register and return the sum. */
5026 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5027 enum machine_mode mode)
5029 unsigned int extra = 0;
5031 if (!reg_offset_addressing_ok_p (mode))
5033 if (virtual_stack_registers_memory_p (x))
5036 /* In theory we should not be seeing addresses of the form reg+0,
5037 but just in case it is generated, optimize it away. */
5038 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5039 return force_reg (Pmode, XEXP (x, 0));
5041 /* Make sure both operands are registers. */
5042 else if (GET_CODE (x) == PLUS)
5043 return gen_rtx_PLUS (Pmode,
5044 force_reg (Pmode, XEXP (x, 0)),
5045 force_reg (Pmode, XEXP (x, 1)));
5047 return force_reg (Pmode, x);
5049 if (GET_CODE (x) == SYMBOL_REF)
5051 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5053 return rs6000_legitimize_tls_address (x, model);
5063 if (!TARGET_POWERPC64)
5071 extra = TARGET_POWERPC64 ? 8 : 12;
5077 if (GET_CODE (x) == PLUS
5078 && GET_CODE (XEXP (x, 0)) == REG
5079 && GET_CODE (XEXP (x, 1)) == CONST_INT
5080 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5082 && !((TARGET_POWERPC64
5083 && (mode == DImode || mode == TImode)
5084 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5085 || SPE_VECTOR_MODE (mode)
5086 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5087 || mode == DImode || mode == DDmode
5088 || mode == TDmode))))
5090 HOST_WIDE_INT high_int, low_int;
5092 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5093 if (low_int >= 0x8000 - extra)
5095 high_int = INTVAL (XEXP (x, 1)) - low_int;
5096 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5097 GEN_INT (high_int)), 0);
5098 return plus_constant (sum, low_int);
5100 else if (GET_CODE (x) == PLUS
5101 && GET_CODE (XEXP (x, 0)) == REG
5102 && GET_CODE (XEXP (x, 1)) != CONST_INT
5103 && GET_MODE_NUNITS (mode) == 1
5104 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5106 || ((mode != DImode && mode != DFmode && mode != DDmode)
5107 || (TARGET_E500_DOUBLE && mode != DDmode)))
5108 && (TARGET_POWERPC64 || mode != DImode)
5109 && !avoiding_indexed_address_p (mode)
5114 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5115 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5117 else if (SPE_VECTOR_MODE (mode)
5118 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5119 || mode == DDmode || mode == TDmode
5120 || mode == DImode)))
5124 /* We accept [reg + reg] and [reg + OFFSET]. */
5126 if (GET_CODE (x) == PLUS)
5128 rtx op1 = XEXP (x, 0);
5129 rtx op2 = XEXP (x, 1);
5132 op1 = force_reg (Pmode, op1);
5134 if (GET_CODE (op2) != REG
5135 && (GET_CODE (op2) != CONST_INT
5136 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5137 || (GET_MODE_SIZE (mode) > 8
5138 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5139 op2 = force_reg (Pmode, op2);
5141 /* We can't always do [reg + reg] for these, because [reg +
5142 reg + offset] is not a legitimate addressing mode. */
5143 y = gen_rtx_PLUS (Pmode, op1, op2);
5145 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5146 return force_reg (Pmode, y);
5151 return force_reg (Pmode, x);
5157 && GET_CODE (x) != CONST_INT
5158 && GET_CODE (x) != CONST_DOUBLE
5160 && GET_MODE_NUNITS (mode) == 1
5161 && (GET_MODE_BITSIZE (mode) <= 32
5162 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5163 && (mode == DFmode || mode == DDmode))))
5165 rtx reg = gen_reg_rtx (Pmode);
5166 emit_insn (gen_elf_high (reg, x));
5167 return gen_rtx_LO_SUM (Pmode, reg, x);
5169 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5172 && ! MACHO_DYNAMIC_NO_PIC_P
5174 && GET_CODE (x) != CONST_INT
5175 && GET_CODE (x) != CONST_DOUBLE
5177 && GET_MODE_NUNITS (mode) == 1
5178 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5179 || (mode != DFmode && mode != DDmode))
5183 rtx reg = gen_reg_rtx (Pmode);
5184 emit_insn (gen_macho_high (reg, x));
5185 return gen_rtx_LO_SUM (Pmode, reg, x);
5188 && GET_CODE (x) == SYMBOL_REF
5189 && constant_pool_expr_p (x)
5190 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5192 return create_TOC_reference (x);
5198 /* Debug version of rs6000_legitimize_address. */
5200 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5206 ret = rs6000_legitimize_address (x, oldx, mode);
5207 insns = get_insns ();
5213 "\nrs6000_legitimize_address: mode %s, old code %s, "
5214 "new code %s, modified\n",
5215 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5216 GET_RTX_NAME (GET_CODE (ret)));
5218 fprintf (stderr, "Original address:\n");
5221 fprintf (stderr, "oldx:\n");
5224 fprintf (stderr, "New address:\n");
5229 fprintf (stderr, "Insns added:\n");
5230 debug_rtx_list (insns, 20);
5236 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5237 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5248 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5249 We need to emit DTP-relative relocations. */
5252 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5257 fputs ("\t.long\t", file);
5260 fputs (DOUBLE_INT_ASM_OP, file);
5265 output_addr_const (file, x);
5266 fputs ("@dtprel+0x8000", file);
5269 /* In the name of slightly smaller debug output, and to cater to
5270 general assembler lossage, recognize various UNSPEC sequences
5271 and turn them back into a direct symbol reference. */
5274 rs6000_delegitimize_address (rtx orig_x)
5278 orig_x = delegitimize_mem_from_attrs (orig_x);
5283 if (GET_CODE (x) == PLUS
5284 && GET_CODE (XEXP (x, 1)) == CONST
5285 && GET_CODE (XEXP (x, 0)) == REG
5286 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5288 y = XEXP (XEXP (x, 1), 0);
5289 if (GET_CODE (y) == UNSPEC
5290 && XINT (y, 1) == UNSPEC_TOCREL)
5292 y = XVECEXP (y, 0, 0);
5293 if (!MEM_P (orig_x))
5296 return replace_equiv_address_nv (orig_x, y);
5304 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5306 static GTY(()) rtx rs6000_tls_symbol;
5308 rs6000_tls_get_addr (void)
5310 if (!rs6000_tls_symbol)
5311 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5313 return rs6000_tls_symbol;
5316 /* Construct the SYMBOL_REF for TLS GOT references. */
5318 static GTY(()) rtx rs6000_got_symbol;
5320 rs6000_got_sym (void)
5322 if (!rs6000_got_symbol)
5324 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5325 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5326 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5329 return rs6000_got_symbol;
5332 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5333 this (thread-local) address. */
5336 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5340 dest = gen_reg_rtx (Pmode);
5341 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5347 tlsreg = gen_rtx_REG (Pmode, 13);
5348 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5352 tlsreg = gen_rtx_REG (Pmode, 2);
5353 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5357 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5361 tmp = gen_reg_rtx (Pmode);
5364 tlsreg = gen_rtx_REG (Pmode, 13);
5365 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5369 tlsreg = gen_rtx_REG (Pmode, 2);
5370 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5374 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5376 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5381 rtx r3, got, tga, tmp1, tmp2, eqv;
5383 /* We currently use relocations like @got@tlsgd for tls, which
5384 means the linker will handle allocation of tls entries, placing
5385 them in the .got section. So use a pointer to the .got section,
5386 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5387 or to secondary GOT sections used by 32-bit -fPIC. */
5389 got = gen_rtx_REG (Pmode, 2);
5393 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5396 rtx gsym = rs6000_got_sym ();
5397 got = gen_reg_rtx (Pmode);
5399 rs6000_emit_move (got, gsym, Pmode);
5405 tmp1 = gen_reg_rtx (Pmode);
5406 tmp2 = gen_reg_rtx (Pmode);
5407 tmp3 = gen_reg_rtx (Pmode);
5408 mem = gen_const_mem (Pmode, tmp1);
5410 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5411 emit_move_insn (tmp1,
5412 gen_rtx_REG (Pmode, LR_REGNO));
5413 emit_move_insn (tmp2, mem);
5414 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5415 last = emit_move_insn (got, tmp3);
5416 set_unique_reg_note (last, REG_EQUAL, gsym);
5421 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5423 r3 = gen_rtx_REG (Pmode, 3);
5424 tga = rs6000_tls_get_addr ();
5426 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5427 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5428 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5429 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5430 else if (DEFAULT_ABI == ABI_V4)
5431 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5436 insn = emit_call_insn (insn);
5437 RTL_CONST_CALL_P (insn) = 1;
5438 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5439 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5440 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5441 insn = get_insns ();
5443 emit_libcall_block (insn, dest, r3, addr);
5445 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5447 r3 = gen_rtx_REG (Pmode, 3);
5448 tga = rs6000_tls_get_addr ();
5450 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5451 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5452 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5453 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5454 else if (DEFAULT_ABI == ABI_V4)
5455 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5460 insn = emit_call_insn (insn);
5461 RTL_CONST_CALL_P (insn) = 1;
5462 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5463 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5464 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5465 insn = get_insns ();
5467 tmp1 = gen_reg_rtx (Pmode);
5468 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5470 emit_libcall_block (insn, tmp1, r3, eqv);
5471 if (rs6000_tls_size == 16)
5474 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5476 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5478 else if (rs6000_tls_size == 32)
5480 tmp2 = gen_reg_rtx (Pmode);
5482 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5484 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5487 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5489 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5493 tmp2 = gen_reg_rtx (Pmode);
5495 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5497 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5499 insn = gen_rtx_SET (Pmode, dest,
5500 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5506 /* IE, or 64-bit offset LE. */
5507 tmp2 = gen_reg_rtx (Pmode);
5509 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5511 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5514 insn = gen_tls_tls_64 (dest, tmp2, addr);
5516 insn = gen_tls_tls_32 (dest, tmp2, addr);
5524 /* Return 1 if X contains a thread-local symbol. */
5527 rs6000_tls_referenced_p (rtx x)
5529 if (! TARGET_HAVE_TLS)
5532 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5535 /* Return 1 if *X is a thread-local symbol. This is the same as
5536 rs6000_tls_symbol_ref except for the type of the unused argument. */
5539 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5541 return RS6000_SYMBOL_REF_TLS_P (*x);
5544 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5545 replace the input X, or the original X if no replacement is called for.
5546 The output parameter *WIN is 1 if the calling macro should goto WIN,
5549 For RS/6000, we wish to handle large displacements off a base
5550 register by splitting the addend across an addiu/addis and the mem insn.
5551 This cuts number of extra insns needed from 3 to 1.
5553 On Darwin, we use this to generate code for floating point constants.
5554 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5555 The Darwin code is inside #if TARGET_MACHO because only then are the
5556 machopic_* functions defined. */
5558 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5559 int opnum, int type,
5560 int ind_levels ATTRIBUTE_UNUSED, int *win)
5562 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5564 /* We must recognize output that we have already generated ourselves. */
5565 if (GET_CODE (x) == PLUS
5566 && GET_CODE (XEXP (x, 0)) == PLUS
5567 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5568 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5569 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5571 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5572 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5573 opnum, (enum reload_type)type);
5579 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5580 && GET_CODE (x) == LO_SUM
5581 && GET_CODE (XEXP (x, 0)) == PLUS
5582 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5583 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5584 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5585 && machopic_operand_p (XEXP (x, 1)))
5587 /* Result of previous invocation of this function on Darwin
5588 floating point constant. */
5589 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5590 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5591 opnum, (enum reload_type)type);
5597 /* Force ld/std non-word aligned offset into base register by wrapping
5599 if (GET_CODE (x) == PLUS
5600 && GET_CODE (XEXP (x, 0)) == REG
5601 && REGNO (XEXP (x, 0)) < 32
5602 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5603 && GET_CODE (XEXP (x, 1)) == CONST_INT
5605 && (INTVAL (XEXP (x, 1)) & 3) != 0
5606 && VECTOR_MEM_NONE_P (mode)
5607 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5608 && TARGET_POWERPC64)
5610 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5611 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5612 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5613 opnum, (enum reload_type) type);
5618 if (GET_CODE (x) == PLUS
5619 && GET_CODE (XEXP (x, 0)) == REG
5620 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5621 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5622 && GET_CODE (XEXP (x, 1)) == CONST_INT
5624 && !SPE_VECTOR_MODE (mode)
5625 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5626 || mode == DDmode || mode == TDmode
5628 && VECTOR_MEM_NONE_P (mode))
5630 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5631 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5633 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5635 /* Check for 32-bit overflow. */
5636 if (high + low != val)
5642 /* Reload the high part into a base reg; leave the low part
5643 in the mem directly. */
5645 x = gen_rtx_PLUS (GET_MODE (x),
5646 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5650 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5651 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5652 opnum, (enum reload_type)type);
5657 if (GET_CODE (x) == SYMBOL_REF
5659 && VECTOR_MEM_NONE_P (mode)
5660 && !SPE_VECTOR_MODE (mode)
5662 && DEFAULT_ABI == ABI_DARWIN
5663 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5665 && DEFAULT_ABI == ABI_V4
5668 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5669 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5673 && (mode != DImode || TARGET_POWERPC64)
5674 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5675 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5680 rtx offset = machopic_gen_offset (x);
5681 x = gen_rtx_LO_SUM (GET_MODE (x),
5682 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5683 gen_rtx_HIGH (Pmode, offset)), offset);
5687 x = gen_rtx_LO_SUM (GET_MODE (x),
5688 gen_rtx_HIGH (Pmode, x), x);
5690 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5691 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5692 opnum, (enum reload_type)type);
5697 /* Reload an offset address wrapped by an AND that represents the
5698 masking of the lower bits. Strip the outer AND and let reload
5699 convert the offset address into an indirect address. For VSX,
5700 force reload to create the address with an AND in a separate
5701 register, because we can't guarantee an altivec register will
5703 if (VECTOR_MEM_ALTIVEC_P (mode)
5704 && GET_CODE (x) == AND
5705 && GET_CODE (XEXP (x, 0)) == PLUS
5706 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5707 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5708 && GET_CODE (XEXP (x, 1)) == CONST_INT
5709 && INTVAL (XEXP (x, 1)) == -16)
5718 && GET_CODE (x) == SYMBOL_REF
5719 && constant_pool_expr_p (x)
5720 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5722 x = create_TOC_reference (x);
5730 /* Debug version of rs6000_legitimize_reload_address. */
5732 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5733 int opnum, int type,
5734 int ind_levels, int *win)
5736 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5739 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5740 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5741 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5745 fprintf (stderr, "Same address returned\n");
5747 fprintf (stderr, "NULL returned\n");
5750 fprintf (stderr, "New address:\n");
5757 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5758 that is a valid memory address for an instruction.
5759 The MODE argument is the machine mode for the MEM expression
5760 that wants to use this address.
5762 On the RS/6000, there are four valid address: a SYMBOL_REF that
5763 refers to a constant pool entry of an address (or the sum of it
5764 plus a constant), a short (16-bit signed) constant plus a register,
5765 the sum of two registers, or a register indirect, possibly with an
5766 auto-increment. For DFmode, DDmode and DImode with a constant plus
5767 register, we must ensure that both words are addressable or PowerPC64
5768 with offset word aligned.
5770 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5771 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5772 because adjacent memory cells are accessed by adding word-sized offsets
5773 during assembly output. */
5775 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5777 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5779 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5780 if (VECTOR_MEM_ALTIVEC_P (mode)
5781 && GET_CODE (x) == AND
5782 && GET_CODE (XEXP (x, 1)) == CONST_INT
5783 && INTVAL (XEXP (x, 1)) == -16)
5786 if (RS6000_SYMBOL_REF_TLS_P (x))
5788 if (legitimate_indirect_address_p (x, reg_ok_strict))
5790 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5791 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5792 && !SPE_VECTOR_MODE (mode)
5795 /* Restrict addressing for DI because of our SUBREG hackery. */
5796 && !(TARGET_E500_DOUBLE
5797 && (mode == DFmode || mode == DDmode || mode == DImode))
5799 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5801 if (virtual_stack_registers_memory_p (x))
5803 if (reg_offset_p && legitimate_small_data_p (mode, x))
5805 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5807 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5810 && GET_CODE (x) == PLUS
5811 && GET_CODE (XEXP (x, 0)) == REG
5812 && (XEXP (x, 0) == virtual_stack_vars_rtx
5813 || XEXP (x, 0) == arg_pointer_rtx)
5814 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5816 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5821 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5823 || (mode != DFmode && mode != DDmode)
5824 || (TARGET_E500_DOUBLE && mode != DDmode))
5825 && (TARGET_POWERPC64 || mode != DImode)
5826 && !avoiding_indexed_address_p (mode)
5827 && legitimate_indexed_address_p (x, reg_ok_strict))
5829 if (GET_CODE (x) == PRE_MODIFY
5833 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5835 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5836 && (TARGET_POWERPC64 || mode != DImode)
5837 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5838 && !SPE_VECTOR_MODE (mode)
5839 /* Restrict addressing for DI because of our SUBREG hackery. */
5840 && !(TARGET_E500_DOUBLE
5841 && (mode == DFmode || mode == DDmode || mode == DImode))
5843 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5844 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5845 || (!avoiding_indexed_address_p (mode)
5846 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5847 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5849 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5854 /* Debug version of rs6000_legitimate_address_p. */
5856 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5859 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5861 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5862 "strict = %d, code = %s\n",
5863 ret ? "true" : "false",
5864 GET_MODE_NAME (mode),
5866 GET_RTX_NAME (GET_CODE (x)));
5872 /* Go to LABEL if ADDR (a legitimate address expression)
5873 has an effect that depends on the machine mode it is used for.
5875 On the RS/6000 this is true of all integral offsets (since AltiVec
5876 and VSX modes don't allow them) or is a pre-increment or decrement.
5878 ??? Except that due to conceptual problems in offsettable_address_p
5879 we can't really report the problems of integral offsets. So leave
5880 this assuming that the adjustable offset must be valid for the
5881 sub-words of a TFmode operand, which is what we had before. */
5884 rs6000_mode_dependent_address (rtx addr)
5886 switch (GET_CODE (addr))
5889 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5890 is considered a legitimate address before reload, so there
5891 are no offset restrictions in that case. Note that this
5892 condition is safe in strict mode because any address involving
5893 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5894 been rejected as illegitimate. */
5895 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5896 && XEXP (addr, 0) != arg_pointer_rtx
5897 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5899 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5900 return val + 12 + 0x8000 >= 0x10000;
5907 /* Auto-increment cases are now treated generically in recog.c. */
5909 return TARGET_UPDATE;
5911 /* AND is only allowed in Altivec loads. */
5922 /* Debug version of rs6000_mode_dependent_address. */
5924 rs6000_debug_mode_dependent_address (rtx addr)
5926 bool ret = rs6000_mode_dependent_address (addr);
5928 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5929 ret ? "true" : "false");
5935 /* Implement FIND_BASE_TERM. */
5938 rs6000_find_base_term (rtx op)
5942 split_const (op, &base, &offset);
5943 if (GET_CODE (base) == UNSPEC)
5944 switch (XINT (base, 1))
5947 case UNSPEC_MACHOPIC_OFFSET:
5948 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5949 for aliasing purposes. */
5950 return XVECEXP (base, 0, 0);
5956 /* More elaborate version of recog's offsettable_memref_p predicate
5957 that works around the ??? note of rs6000_mode_dependent_address.
5958 In particular it accepts
5960 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5962 in 32-bit mode, that the recog predicate rejects. */
5965 rs6000_offsettable_memref_p (rtx op)
5970 /* First mimic offsettable_memref_p. */
5971 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5974 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5975 the latter predicate knows nothing about the mode of the memory
5976 reference and, therefore, assumes that it is the largest supported
5977 mode (TFmode). As a consequence, legitimate offsettable memory
5978 references are rejected. rs6000_legitimate_offset_address_p contains
5979 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5980 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5983 /* Change register usage conditional on target flags. */
5985 rs6000_conditional_register_usage (void)
5989 /* Set MQ register fixed (already call_used) if not POWER
5990 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5995 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5997 fixed_regs[13] = call_used_regs[13]
5998 = call_really_used_regs[13] = 1;
6000 /* Conditionally disable FPRs. */
6001 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6002 for (i = 32; i < 64; i++)
6003 fixed_regs[i] = call_used_regs[i]
6004 = call_really_used_regs[i] = 1;
6006 /* The TOC register is not killed across calls in a way that is
6007 visible to the compiler. */
6008 if (DEFAULT_ABI == ABI_AIX)
6009 call_really_used_regs[2] = 0;
6011 if (DEFAULT_ABI == ABI_V4
6012 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6014 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6016 if (DEFAULT_ABI == ABI_V4
6017 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6019 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6020 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6021 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6023 if (DEFAULT_ABI == ABI_DARWIN
6024 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6025 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6026 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6027 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6029 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6030 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6031 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6035 global_regs[SPEFSCR_REGNO] = 1;
6036 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6037 registers in prologues and epilogues. We no longer use r14
6038 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6039 pool for link-compatibility with older versions of GCC. Once
6040 "old" code has died out, we can return r14 to the allocation
6043 = call_used_regs[14]
6044 = call_really_used_regs[14] = 1;
6047 if (!TARGET_ALTIVEC && !TARGET_VSX)
6049 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6050 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6051 call_really_used_regs[VRSAVE_REGNO] = 1;
6054 if (TARGET_ALTIVEC || TARGET_VSX)
6055 global_regs[VSCR_REGNO] = 1;
6057 if (TARGET_ALTIVEC_ABI)
6059 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6060 call_used_regs[i] = call_really_used_regs[i] = 1;
6062 /* AIX reserves VR20:31 in non-extended ABI mode. */
6064 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6065 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6069 /* Try to output insns to set TARGET equal to the constant C if it can
6070 be done in less than N insns. Do all computations in MODE.
6071 Returns the place where the output has been placed if it can be
6072 done and the insns have been emitted. If it would take more than N
6073 insns, zero is returned and no insns and emitted. */
6076 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6077 rtx source, int n ATTRIBUTE_UNUSED)
6079 rtx result, insn, set;
6080 HOST_WIDE_INT c0, c1;
6087 dest = gen_reg_rtx (mode);
6088 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6092 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6094 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6095 GEN_INT (INTVAL (source)
6096 & (~ (HOST_WIDE_INT) 0xffff))));
6097 emit_insn (gen_rtx_SET (VOIDmode, dest,
6098 gen_rtx_IOR (SImode, copy_rtx (result),
6099 GEN_INT (INTVAL (source) & 0xffff))));
6104 switch (GET_CODE (source))
6107 c0 = INTVAL (source);
6112 #if HOST_BITS_PER_WIDE_INT >= 64
6113 c0 = CONST_DOUBLE_LOW (source);
6116 c0 = CONST_DOUBLE_LOW (source);
6117 c1 = CONST_DOUBLE_HIGH (source);
6125 result = rs6000_emit_set_long_const (dest, c0, c1);
6132 insn = get_last_insn ();
6133 set = single_set (insn);
6134 if (! CONSTANT_P (SET_SRC (set)))
6135 set_unique_reg_note (insn, REG_EQUAL, source);
6140 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6141 fall back to a straight forward decomposition. We do this to avoid
6142 exponential run times encountered when looking for longer sequences
6143 with rs6000_emit_set_const. */
6145 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6147 if (!TARGET_POWERPC64)
6149 rtx operand1, operand2;
6151 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6153 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6155 emit_move_insn (operand1, GEN_INT (c1));
6156 emit_move_insn (operand2, GEN_INT (c2));
6160 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6163 ud2 = (c1 & 0xffff0000) >> 16;
6164 #if HOST_BITS_PER_WIDE_INT >= 64
6168 ud4 = (c2 & 0xffff0000) >> 16;
6170 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6171 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6174 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6176 emit_move_insn (dest, GEN_INT (ud1));
6179 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6180 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6183 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6186 emit_move_insn (dest, GEN_INT (ud2 << 16));
6188 emit_move_insn (copy_rtx (dest),
6189 gen_rtx_IOR (DImode, copy_rtx (dest),
6192 else if (ud3 == 0 && ud4 == 0)
6194 gcc_assert (ud2 & 0x8000);
6195 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6198 emit_move_insn (copy_rtx (dest),
6199 gen_rtx_IOR (DImode, copy_rtx (dest),
6201 emit_move_insn (copy_rtx (dest),
6202 gen_rtx_ZERO_EXTEND (DImode,
6203 gen_lowpart (SImode,
6206 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6207 || (ud4 == 0 && ! (ud3 & 0x8000)))
6210 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6213 emit_move_insn (dest, GEN_INT (ud3 << 16));
6216 emit_move_insn (copy_rtx (dest),
6217 gen_rtx_IOR (DImode, copy_rtx (dest),
6219 emit_move_insn (copy_rtx (dest),
6220 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6223 emit_move_insn (copy_rtx (dest),
6224 gen_rtx_IOR (DImode, copy_rtx (dest),
6230 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6233 emit_move_insn (dest, GEN_INT (ud4 << 16));
6236 emit_move_insn (copy_rtx (dest),
6237 gen_rtx_IOR (DImode, copy_rtx (dest),
6240 emit_move_insn (copy_rtx (dest),
6241 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6244 emit_move_insn (copy_rtx (dest),
6245 gen_rtx_IOR (DImode, copy_rtx (dest),
6246 GEN_INT (ud2 << 16)));
6248 emit_move_insn (copy_rtx (dest),
6249 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6255 /* Helper for the following. Get rid of [r+r] memory refs
6256 in cases where it won't work (TImode, TFmode, TDmode). */
6259 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6261 if (GET_CODE (operands[0]) == MEM
6262 && GET_CODE (XEXP (operands[0], 0)) != REG
6263 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6264 && ! reload_in_progress)
6266 = replace_equiv_address (operands[0],
6267 copy_addr_to_reg (XEXP (operands[0], 0)));
6269 if (GET_CODE (operands[1]) == MEM
6270 && GET_CODE (XEXP (operands[1], 0)) != REG
6271 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6272 && ! reload_in_progress)
6274 = replace_equiv_address (operands[1],
6275 copy_addr_to_reg (XEXP (operands[1], 0)));
6278 /* Emit a move from SOURCE to DEST in mode MODE. */
6280 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6284 operands[1] = source;
6286 if (TARGET_DEBUG_ADDR)
6289 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6290 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6291 GET_MODE_NAME (mode),
6294 can_create_pseudo_p ());
6296 fprintf (stderr, "source:\n");
6300 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6301 if (GET_CODE (operands[1]) == CONST_DOUBLE
6302 && ! FLOAT_MODE_P (mode)
6303 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6305 /* FIXME. This should never happen. */
6306 /* Since it seems that it does, do the safe thing and convert
6308 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6310 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6311 || FLOAT_MODE_P (mode)
6312 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6313 || CONST_DOUBLE_LOW (operands[1]) < 0)
6314 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6315 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6317 /* Check if GCC is setting up a block move that will end up using FP
6318 registers as temporaries. We must make sure this is acceptable. */
6319 if (GET_CODE (operands[0]) == MEM
6320 && GET_CODE (operands[1]) == MEM
6322 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6323 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6324 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6325 ? 32 : MEM_ALIGN (operands[0])))
6326 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6328 : MEM_ALIGN (operands[1]))))
6329 && ! MEM_VOLATILE_P (operands [0])
6330 && ! MEM_VOLATILE_P (operands [1]))
6332 emit_move_insn (adjust_address (operands[0], SImode, 0),
6333 adjust_address (operands[1], SImode, 0));
6334 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6335 adjust_address (copy_rtx (operands[1]), SImode, 4));
6339 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6340 in the secondary_reload phase, which evidently overwrites the CONST_INT
6342 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6345 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6346 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6348 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6350 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6352 if (TARGET_DEBUG_ADDR)
6354 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6358 rs6000_emit_move (tmp, add_op0, Pmode);
6359 emit_insn (gen_rtx_SET (VOIDmode, dest,
6360 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6365 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6366 && !gpc_reg_operand (operands[1], mode))
6367 operands[1] = force_reg (mode, operands[1]);
6369 if (mode == SFmode && ! TARGET_POWERPC
6370 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6371 && GET_CODE (operands[0]) == MEM)
6375 if (reload_in_progress || reload_completed)
6376 regnum = true_regnum (operands[1]);
6377 else if (GET_CODE (operands[1]) == REG)
6378 regnum = REGNO (operands[1]);
6382 /* If operands[1] is a register, on POWER it may have
6383 double-precision data in it, so truncate it to single
6385 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6388 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6389 : gen_reg_rtx (mode));
6390 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6391 operands[1] = newreg;
6395 /* Recognize the case where operand[1] is a reference to thread-local
6396 data and load its address to a register. */
6397 if (rs6000_tls_referenced_p (operands[1]))
6399 enum tls_model model;
6400 rtx tmp = operands[1];
6403 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6405 addend = XEXP (XEXP (tmp, 0), 1);
6406 tmp = XEXP (XEXP (tmp, 0), 0);
6409 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6410 model = SYMBOL_REF_TLS_MODEL (tmp);
6411 gcc_assert (model != 0);
6413 tmp = rs6000_legitimize_tls_address (tmp, model);
6416 tmp = gen_rtx_PLUS (mode, tmp, addend);
6417 tmp = force_operand (tmp, operands[0]);
6422 /* Handle the case where reload calls us with an invalid address. */
6423 if (reload_in_progress && mode == Pmode
6424 && (! general_operand (operands[1], mode)
6425 || ! nonimmediate_operand (operands[0], mode)))
6428 /* 128-bit constant floating-point values on Darwin should really be
6429 loaded as two parts. */
6430 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6431 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6433 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6434 know how to get a DFmode SUBREG of a TFmode. */
6435 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6436 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6437 simplify_gen_subreg (imode, operands[1], mode, 0),
6439 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6440 GET_MODE_SIZE (imode)),
6441 simplify_gen_subreg (imode, operands[1], mode,
6442 GET_MODE_SIZE (imode)),
6447 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6448 cfun->machine->sdmode_stack_slot =
6449 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6451 if (reload_in_progress
6453 && MEM_P (operands[0])
6454 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6455 && REG_P (operands[1]))
6457 if (FP_REGNO_P (REGNO (operands[1])))
6459 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6460 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6461 emit_insn (gen_movsd_store (mem, operands[1]));
6463 else if (INT_REGNO_P (REGNO (operands[1])))
6465 rtx mem = adjust_address_nv (operands[0], mode, 4);
6466 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6467 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6473 if (reload_in_progress
6475 && REG_P (operands[0])
6476 && MEM_P (operands[1])
6477 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6479 if (FP_REGNO_P (REGNO (operands[0])))
6481 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6482 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6483 emit_insn (gen_movsd_load (operands[0], mem));
6485 else if (INT_REGNO_P (REGNO (operands[0])))
6487 rtx mem = adjust_address_nv (operands[1], mode, 4);
6488 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6489 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6496 /* FIXME: In the long term, this switch statement should go away
6497 and be replaced by a sequence of tests based on things like
6503 if (CONSTANT_P (operands[1])
6504 && GET_CODE (operands[1]) != CONST_INT)
6505 operands[1] = force_const_mem (mode, operands[1]);
6510 rs6000_eliminate_indexed_memrefs (operands);
6517 if (CONSTANT_P (operands[1])
6518 && ! easy_fp_constant (operands[1], mode))
6519 operands[1] = force_const_mem (mode, operands[1]);
6532 if (CONSTANT_P (operands[1])
6533 && !easy_vector_constant (operands[1], mode))
6534 operands[1] = force_const_mem (mode, operands[1]);
6539 /* Use default pattern for address of ELF small data */
6542 && DEFAULT_ABI == ABI_V4
6543 && (GET_CODE (operands[1]) == SYMBOL_REF
6544 || GET_CODE (operands[1]) == CONST)
6545 && small_data_operand (operands[1], mode))
6547 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6551 if (DEFAULT_ABI == ABI_V4
6552 && mode == Pmode && mode == SImode
6553 && flag_pic == 1 && got_operand (operands[1], mode))
6555 emit_insn (gen_movsi_got (operands[0], operands[1]));
6559 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6563 && CONSTANT_P (operands[1])
6564 && GET_CODE (operands[1]) != HIGH
6565 && GET_CODE (operands[1]) != CONST_INT)
6567 rtx target = (!can_create_pseudo_p ()
6569 : gen_reg_rtx (mode));
6571 /* If this is a function address on -mcall-aixdesc,
6572 convert it to the address of the descriptor. */
6573 if (DEFAULT_ABI == ABI_AIX
6574 && GET_CODE (operands[1]) == SYMBOL_REF
6575 && XSTR (operands[1], 0)[0] == '.')
6577 const char *name = XSTR (operands[1], 0);
6579 while (*name == '.')
6581 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6582 CONSTANT_POOL_ADDRESS_P (new_ref)
6583 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6584 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6585 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6586 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6587 operands[1] = new_ref;
6590 if (DEFAULT_ABI == ABI_DARWIN)
6593 if (MACHO_DYNAMIC_NO_PIC_P)
6595 /* Take care of any required data indirection. */
6596 operands[1] = rs6000_machopic_legitimize_pic_address (
6597 operands[1], mode, operands[0]);
6598 if (operands[0] != operands[1])
6599 emit_insn (gen_rtx_SET (VOIDmode,
6600 operands[0], operands[1]));
6604 emit_insn (gen_macho_high (target, operands[1]));
6605 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6609 emit_insn (gen_elf_high (target, operands[1]));
6610 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6614 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6615 and we have put it in the TOC, we just need to make a TOC-relative
6618 && GET_CODE (operands[1]) == SYMBOL_REF
6619 && constant_pool_expr_p (operands[1])
6620 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6621 get_pool_mode (operands[1])))
6623 operands[1] = create_TOC_reference (operands[1]);
6625 else if (mode == Pmode
6626 && CONSTANT_P (operands[1])
6627 && ((GET_CODE (operands[1]) != CONST_INT
6628 && ! easy_fp_constant (operands[1], mode))
6629 || (GET_CODE (operands[1]) == CONST_INT
6630 && num_insns_constant (operands[1], mode) > 2)
6631 || (GET_CODE (operands[0]) == REG
6632 && FP_REGNO_P (REGNO (operands[0]))))
6633 && GET_CODE (operands[1]) != HIGH
6634 && ! legitimate_constant_pool_address_p (operands[1])
6635 && ! toc_relative_expr_p (operands[1]))
6639 /* Darwin uses a special PIC legitimizer. */
6640 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6643 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6645 if (operands[0] != operands[1])
6646 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6651 /* If we are to limit the number of things we put in the TOC and
6652 this is a symbol plus a constant we can add in one insn,
6653 just put the symbol in the TOC and add the constant. Don't do
6654 this if reload is in progress. */
6655 if (GET_CODE (operands[1]) == CONST
6656 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6657 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6658 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6659 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6660 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6661 && ! side_effects_p (operands[0]))
6664 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6665 rtx other = XEXP (XEXP (operands[1], 0), 1);
6667 sym = force_reg (mode, sym);
6668 emit_insn (gen_add3_insn (operands[0], sym, other));
6672 operands[1] = force_const_mem (mode, operands[1]);
6675 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6676 && constant_pool_expr_p (XEXP (operands[1], 0))
6677 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6678 get_pool_constant (XEXP (operands[1], 0)),
6679 get_pool_mode (XEXP (operands[1], 0))))
6682 = gen_const_mem (mode,
6683 create_TOC_reference (XEXP (operands[1], 0)));
6684 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6690 rs6000_eliminate_indexed_memrefs (operands);
6694 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6696 gen_rtx_SET (VOIDmode,
6697 operands[0], operands[1]),
6698 gen_rtx_CLOBBER (VOIDmode,
6699 gen_rtx_SCRATCH (SImode)))));
6705 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6708 /* Above, we may have called force_const_mem which may have returned
6709 an invalid address. If we can, fix this up; otherwise, reload will
6710 have to deal with it. */
6711 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6712 operands[1] = validize_mem (operands[1]);
6715 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6718 /* Nonzero if we can use a floating-point register to pass this arg. */
6719 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6720 (SCALAR_FLOAT_MODE_P (MODE) \
6721 && (CUM)->fregno <= FP_ARG_MAX_REG \
6722 && TARGET_HARD_FLOAT && TARGET_FPRS)
6724 /* Nonzero if we can use an AltiVec register to pass this arg. */
6725 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6726 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6727 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6728 && TARGET_ALTIVEC_ABI \
6731 /* Return a nonzero value to say to return the function value in
6732 memory, just as large structures are always returned. TYPE will be
6733 the data type of the value, and FNTYPE will be the type of the
6734 function doing the returning, or @code{NULL} for libcalls.
6736 The AIX ABI for the RS/6000 specifies that all structures are
6737 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6738 specifies that structures <= 8 bytes are returned in r3/r4, but a
6739 draft put them in memory, and GCC used to implement the draft
6740 instead of the final standard. Therefore, aix_struct_return
6741 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6742 compatibility can change DRAFT_V4_STRUCT_RET to override the
6743 default, and -m switches get the final word. See
6744 rs6000_override_options for more details.
6746 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6747 long double support is enabled. These values are returned in memory.
6749 int_size_in_bytes returns -1 for variable size objects, which go in
6750 memory always. The cast to unsigned makes -1 > 8. */
6753 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6755 /* In the darwin64 abi, try to use registers for larger structs
6757 if (rs6000_darwin64_abi
6758 && TREE_CODE (type) == RECORD_TYPE
6759 && int_size_in_bytes (type) > 0)
6761 CUMULATIVE_ARGS valcum;
6765 valcum.fregno = FP_ARG_MIN_REG;
6766 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6767 /* Do a trial code generation as if this were going to be passed
6768 as an argument; if any part goes in memory, we return NULL. */
6769 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6772 /* Otherwise fall through to more conventional ABI rules. */
6775 if (AGGREGATE_TYPE_P (type)
6776 && (aix_struct_return
6777 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6780 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6781 modes only exist for GCC vector types if -maltivec. */
6782 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6783 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6786 /* Return synthetic vectors in memory. */
6787 if (TREE_CODE (type) == VECTOR_TYPE
6788 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6790 static bool warned_for_return_big_vectors = false;
6791 if (!warned_for_return_big_vectors)
6793 warning (0, "GCC vector returned by reference: "
6794 "non-standard ABI extension with no compatibility guarantee");
6795 warned_for_return_big_vectors = true;
6800 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6806 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6807 for a call to a function whose data type is FNTYPE.
6808 For a library call, FNTYPE is 0.
6810 For incoming args we set the number of arguments in the prototype large
6811 so we never return a PARALLEL. */
6814 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6815 rtx libname ATTRIBUTE_UNUSED, int incoming,
6816 int libcall, int n_named_args)
6818 static CUMULATIVE_ARGS zero_cumulative;
6820 *cum = zero_cumulative;
6822 cum->fregno = FP_ARG_MIN_REG;
6823 cum->vregno = ALTIVEC_ARG_MIN_REG;
6824 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6825 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6826 ? CALL_LIBCALL : CALL_NORMAL);
6827 cum->sysv_gregno = GP_ARG_MIN_REG;
6828 cum->stdarg = fntype
6829 && (TYPE_ARG_TYPES (fntype) != 0
6830 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6831 != void_type_node));
6833 cum->nargs_prototype = 0;
6834 if (incoming || cum->prototype)
6835 cum->nargs_prototype = n_named_args;
6837 /* Check for a longcall attribute. */
6838 if ((!fntype && rs6000_default_long_calls)
6840 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6841 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6842 cum->call_cookie |= CALL_LONG;
6844 if (TARGET_DEBUG_ARG)
6846 fprintf (stderr, "\ninit_cumulative_args:");
6849 tree ret_type = TREE_TYPE (fntype);
6850 fprintf (stderr, " ret code = %s,",
6851 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6854 if (cum->call_cookie & CALL_LONG)
6855 fprintf (stderr, " longcall,");
6857 fprintf (stderr, " proto = %d, nargs = %d\n",
6858 cum->prototype, cum->nargs_prototype);
6863 && TARGET_ALTIVEC_ABI
6864 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6866 error ("cannot return value in vector register because"
6867 " altivec instructions are disabled, use -maltivec"
6872 /* Return true if TYPE must be passed on the stack and not in registers. */
6875 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6877 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6878 return must_pass_in_stack_var_size (mode, type);
6880 return must_pass_in_stack_var_size_or_pad (mode, type);
6883 /* If defined, a C expression which determines whether, and in which
6884 direction, to pad out an argument with extra space. The value
6885 should be of type `enum direction': either `upward' to pad above
6886 the argument, `downward' to pad below, or `none' to inhibit
6889 For the AIX ABI structs are always stored left shifted in their
6893 function_arg_padding (enum machine_mode mode, const_tree type)
6895 #ifndef AGGREGATE_PADDING_FIXED
6896 #define AGGREGATE_PADDING_FIXED 0
6898 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6899 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6902 if (!AGGREGATE_PADDING_FIXED)
6904 /* GCC used to pass structures of the same size as integer types as
6905 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6906 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6907 passed padded downward, except that -mstrict-align further
6908 muddied the water in that multi-component structures of 2 and 4
6909 bytes in size were passed padded upward.
6911 The following arranges for best compatibility with previous
6912 versions of gcc, but removes the -mstrict-align dependency. */
6913 if (BYTES_BIG_ENDIAN)
6915 HOST_WIDE_INT size = 0;
6917 if (mode == BLKmode)
6919 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6920 size = int_size_in_bytes (type);
6923 size = GET_MODE_SIZE (mode);
6925 if (size == 1 || size == 2 || size == 4)
6931 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6933 if (type != 0 && AGGREGATE_TYPE_P (type))
6937 /* Fall back to the default. */
6938 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6941 /* If defined, a C expression that gives the alignment boundary, in bits,
6942 of an argument with the specified mode and type. If it is not defined,
6943 PARM_BOUNDARY is used for all arguments.
6945 V.4 wants long longs and doubles to be double word aligned. Just
6946 testing the mode size is a boneheaded way to do this as it means
6947 that other types such as complex int are also double word aligned.
6948 However, we're stuck with this because changing the ABI might break
6949 existing library interfaces.
6951 Doubleword align SPE vectors.
6952 Quadword align Altivec vectors.
6953 Quadword align large synthetic vector types. */
6956 function_arg_boundary (enum machine_mode mode, tree type)
6958 if (DEFAULT_ABI == ABI_V4
6959 && (GET_MODE_SIZE (mode) == 8
6960 || (TARGET_HARD_FLOAT
6962 && (mode == TFmode || mode == TDmode))))
6964 else if (SPE_VECTOR_MODE (mode)
6965 || (type && TREE_CODE (type) == VECTOR_TYPE
6966 && int_size_in_bytes (type) >= 8
6967 && int_size_in_bytes (type) < 16))
6969 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6970 || (type && TREE_CODE (type) == VECTOR_TYPE
6971 && int_size_in_bytes (type) >= 16))
6973 else if (rs6000_darwin64_abi && mode == BLKmode
6974 && type && TYPE_ALIGN (type) > 64)
6977 return PARM_BOUNDARY;
6980 /* For a function parm of MODE and TYPE, return the starting word in
6981 the parameter area. NWORDS of the parameter area are already used. */
6984 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6987 unsigned int parm_offset;
6989 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6990 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6991 return nwords + (-(parm_offset + nwords) & align);
6994 /* Compute the size (in words) of a function argument. */
6996 static unsigned long
6997 rs6000_arg_size (enum machine_mode mode, tree type)
7001 if (mode != BLKmode)
7002 size = GET_MODE_SIZE (mode);
7004 size = int_size_in_bytes (type);
7007 return (size + 3) >> 2;
7009 return (size + 7) >> 3;
7012 /* Use this to flush pending int fields. */
7015 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7016 HOST_WIDE_INT bitpos)
7018 unsigned int startbit, endbit;
7019 int intregs, intoffset;
7020 enum machine_mode mode;
7022 if (cum->intoffset == -1)
7025 intoffset = cum->intoffset;
7026 cum->intoffset = -1;
7028 if (intoffset % BITS_PER_WORD != 0)
7030 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7032 if (mode == BLKmode)
7034 /* We couldn't find an appropriate mode, which happens,
7035 e.g., in packed structs when there are 3 bytes to load.
7036 Back intoffset back to the beginning of the word in this
7038 intoffset = intoffset & -BITS_PER_WORD;
7042 startbit = intoffset & -BITS_PER_WORD;
7043 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7044 intregs = (endbit - startbit) / BITS_PER_WORD;
7045 cum->words += intregs;
7048 /* The darwin64 ABI calls for us to recurse down through structs,
7049 looking for elements passed in registers. Unfortunately, we have
7050 to track int register count here also because of misalignments
7051 in powerpc alignment mode. */
7054 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7056 HOST_WIDE_INT startbitpos)
7060 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7061 if (TREE_CODE (f) == FIELD_DECL)
7063 HOST_WIDE_INT bitpos = startbitpos;
7064 tree ftype = TREE_TYPE (f);
7065 enum machine_mode mode;
7066 if (ftype == error_mark_node)
7068 mode = TYPE_MODE (ftype);
7070 if (DECL_SIZE (f) != 0
7071 && host_integerp (bit_position (f), 1))
7072 bitpos += int_bit_position (f);
7074 /* ??? FIXME: else assume zero offset. */
7076 if (TREE_CODE (ftype) == RECORD_TYPE)
7077 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7078 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7080 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7081 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7082 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7084 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7086 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7090 else if (cum->intoffset == -1)
7091 cum->intoffset = bitpos;
7095 /* Update the data in CUM to advance over an argument
7096 of mode MODE and data type TYPE.
7097 (TYPE is null for libcalls where that information may not be available.)
7099 Note that for args passed by reference, function_arg will be called
7100 with MODE and TYPE set to that of the pointer to the arg, not the arg
7104 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7105 tree type, int named, int depth)
7109 /* Only tick off an argument if we're not recursing. */
7111 cum->nargs_prototype--;
7113 if (TARGET_ALTIVEC_ABI
7114 && (ALTIVEC_VECTOR_MODE (mode)
7115 || VSX_VECTOR_MODE (mode)
7116 || (type && TREE_CODE (type) == VECTOR_TYPE
7117 && int_size_in_bytes (type) == 16)))
7121 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7124 if (!TARGET_ALTIVEC)
7125 error ("cannot pass argument in vector register because"
7126 " altivec instructions are disabled, use -maltivec"
7129 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7130 even if it is going to be passed in a vector register.
7131 Darwin does the same for variable-argument functions. */
7132 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7133 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7143 /* Vector parameters must be 16-byte aligned. This places
7144 them at 2 mod 4 in terms of words in 32-bit mode, since
7145 the parameter save area starts at offset 24 from the
7146 stack. In 64-bit mode, they just have to start on an
7147 even word, since the parameter save area is 16-byte
7148 aligned. Space for GPRs is reserved even if the argument
7149 will be passed in memory. */
7151 align = (2 - cum->words) & 3;
7153 align = cum->words & 1;
7154 cum->words += align + rs6000_arg_size (mode, type);
7156 if (TARGET_DEBUG_ARG)
7158 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7160 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7161 cum->nargs_prototype, cum->prototype,
7162 GET_MODE_NAME (mode));
7166 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7168 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7171 else if (rs6000_darwin64_abi
7173 && TREE_CODE (type) == RECORD_TYPE
7174 && (size = int_size_in_bytes (type)) > 0)
7176 /* Variable sized types have size == -1 and are
7177 treated as if consisting entirely of ints.
7178 Pad to 16 byte boundary if needed. */
7179 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7180 && (cum->words % 2) != 0)
7182 /* For varargs, we can just go up by the size of the struct. */
7184 cum->words += (size + 7) / 8;
7187 /* It is tempting to say int register count just goes up by
7188 sizeof(type)/8, but this is wrong in a case such as
7189 { int; double; int; } [powerpc alignment]. We have to
7190 grovel through the fields for these too. */
7192 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7193 rs6000_darwin64_record_arg_advance_flush (cum,
7194 size * BITS_PER_UNIT);
7197 else if (DEFAULT_ABI == ABI_V4)
7199 if (TARGET_HARD_FLOAT && TARGET_FPRS
7200 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7201 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7202 || (mode == TFmode && !TARGET_IEEEQUAD)
7203 || mode == SDmode || mode == DDmode || mode == TDmode))
7205 /* _Decimal128 must use an even/odd register pair. This assumes
7206 that the register number is odd when fregno is odd. */
7207 if (mode == TDmode && (cum->fregno % 2) == 1)
7210 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7211 <= FP_ARG_V4_MAX_REG)
7212 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7215 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7216 if (mode == DFmode || mode == TFmode
7217 || mode == DDmode || mode == TDmode)
7218 cum->words += cum->words & 1;
7219 cum->words += rs6000_arg_size (mode, type);
7224 int n_words = rs6000_arg_size (mode, type);
7225 int gregno = cum->sysv_gregno;
7227 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7228 (r7,r8) or (r9,r10). As does any other 2 word item such
7229 as complex int due to a historical mistake. */
7231 gregno += (1 - gregno) & 1;
7233 /* Multi-reg args are not split between registers and stack. */
7234 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7236 /* Long long and SPE vectors are aligned on the stack.
7237 So are other 2 word items such as complex int due to
7238 a historical mistake. */
7240 cum->words += cum->words & 1;
7241 cum->words += n_words;
7244 /* Note: continuing to accumulate gregno past when we've started
7245 spilling to the stack indicates the fact that we've started
7246 spilling to the stack to expand_builtin_saveregs. */
7247 cum->sysv_gregno = gregno + n_words;
7250 if (TARGET_DEBUG_ARG)
7252 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7253 cum->words, cum->fregno);
7254 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7255 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7256 fprintf (stderr, "mode = %4s, named = %d\n",
7257 GET_MODE_NAME (mode), named);
7262 int n_words = rs6000_arg_size (mode, type);
7263 int start_words = cum->words;
7264 int align_words = rs6000_parm_start (mode, type, start_words);
7266 cum->words = align_words + n_words;
7268 if (SCALAR_FLOAT_MODE_P (mode)
7269 && TARGET_HARD_FLOAT && TARGET_FPRS)
7271 /* _Decimal128 must be passed in an even/odd float register pair.
7272 This assumes that the register number is odd when fregno is
7274 if (mode == TDmode && (cum->fregno % 2) == 1)
7276 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7279 if (TARGET_DEBUG_ARG)
7281 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7282 cum->words, cum->fregno);
7283 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7284 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7285 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7286 named, align_words - start_words, depth);
7292 spe_build_register_parallel (enum machine_mode mode, int gregno)
7299 r1 = gen_rtx_REG (DImode, gregno);
7300 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7301 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7305 r1 = gen_rtx_REG (DImode, gregno);
7306 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7307 r3 = gen_rtx_REG (DImode, gregno + 2);
7308 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7309 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7312 r1 = gen_rtx_REG (DImode, gregno);
7313 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7314 r3 = gen_rtx_REG (DImode, gregno + 2);
7315 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7316 r5 = gen_rtx_REG (DImode, gregno + 4);
7317 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7318 r7 = gen_rtx_REG (DImode, gregno + 6);
7319 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7320 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7327 /* Determine where to put a SIMD argument on the SPE. */
7329 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7332 int gregno = cum->sysv_gregno;
7334 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7335 are passed and returned in a pair of GPRs for ABI compatibility. */
7336 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7337 || mode == DCmode || mode == TCmode))
7339 int n_words = rs6000_arg_size (mode, type);
7341 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7343 gregno += (1 - gregno) & 1;
7345 /* Multi-reg args are not split between registers and stack. */
7346 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7349 return spe_build_register_parallel (mode, gregno);
7353 int n_words = rs6000_arg_size (mode, type);
7355 /* SPE vectors are put in odd registers. */
7356 if (n_words == 2 && (gregno & 1) == 0)
7359 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7362 enum machine_mode m = SImode;
7364 r1 = gen_rtx_REG (m, gregno);
7365 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7366 r2 = gen_rtx_REG (m, gregno + 1);
7367 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7368 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7375 if (gregno <= GP_ARG_MAX_REG)
7376 return gen_rtx_REG (mode, gregno);
7382 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7383 structure between cum->intoffset and bitpos to integer registers. */
7386 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7387 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7389 enum machine_mode mode;
7391 unsigned int startbit, endbit;
7392 int this_regno, intregs, intoffset;
7395 if (cum->intoffset == -1)
7398 intoffset = cum->intoffset;
7399 cum->intoffset = -1;
7401 /* If this is the trailing part of a word, try to only load that
7402 much into the register. Otherwise load the whole register. Note
7403 that in the latter case we may pick up unwanted bits. It's not a
7404 problem at the moment but may wish to revisit. */
7406 if (intoffset % BITS_PER_WORD != 0)
7408 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7410 if (mode == BLKmode)
7412 /* We couldn't find an appropriate mode, which happens,
7413 e.g., in packed structs when there are 3 bytes to load.
7414 Back intoffset back to the beginning of the word in this
7416 intoffset = intoffset & -BITS_PER_WORD;
7423 startbit = intoffset & -BITS_PER_WORD;
7424 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7425 intregs = (endbit - startbit) / BITS_PER_WORD;
7426 this_regno = cum->words + intoffset / BITS_PER_WORD;
7428 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7431 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7435 intoffset /= BITS_PER_UNIT;
7438 regno = GP_ARG_MIN_REG + this_regno;
7439 reg = gen_rtx_REG (mode, regno);
7441 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7444 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7448 while (intregs > 0);
7451 /* Recursive workhorse for the following. */
7454 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7455 HOST_WIDE_INT startbitpos, rtx rvec[],
7460 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7461 if (TREE_CODE (f) == FIELD_DECL)
7463 HOST_WIDE_INT bitpos = startbitpos;
7464 tree ftype = TREE_TYPE (f);
7465 enum machine_mode mode;
7466 if (ftype == error_mark_node)
7468 mode = TYPE_MODE (ftype);
7470 if (DECL_SIZE (f) != 0
7471 && host_integerp (bit_position (f), 1))
7472 bitpos += int_bit_position (f);
7474 /* ??? FIXME: else assume zero offset. */
7476 if (TREE_CODE (ftype) == RECORD_TYPE)
7477 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7478 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7483 case SCmode: mode = SFmode; break;
7484 case DCmode: mode = DFmode; break;
7485 case TCmode: mode = TFmode; break;
7489 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7491 = gen_rtx_EXPR_LIST (VOIDmode,
7492 gen_rtx_REG (mode, cum->fregno++),
7493 GEN_INT (bitpos / BITS_PER_UNIT));
7494 if (mode == TFmode || mode == TDmode)
7497 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7499 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7501 = gen_rtx_EXPR_LIST (VOIDmode,
7502 gen_rtx_REG (mode, cum->vregno++),
7503 GEN_INT (bitpos / BITS_PER_UNIT));
7505 else if (cum->intoffset == -1)
7506 cum->intoffset = bitpos;
7510 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7511 the register(s) to be used for each field and subfield of a struct
7512 being passed by value, along with the offset of where the
7513 register's value may be found in the block. FP fields go in FP
7514 register, vector fields go in vector registers, and everything
7515 else goes in int registers, packed as in memory.
7517 This code is also used for function return values. RETVAL indicates
7518 whether this is the case.
7520 Much of this is taken from the SPARC V9 port, which has a similar
7521 calling convention. */
7524 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7525 int named, bool retval)
7527 rtx rvec[FIRST_PSEUDO_REGISTER];
7528 int k = 1, kbase = 1;
7529 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7530 /* This is a copy; modifications are not visible to our caller. */
7531 CUMULATIVE_ARGS copy_cum = *orig_cum;
7532 CUMULATIVE_ARGS *cum = ©_cum;
7534 /* Pad to 16 byte boundary if needed. */
7535 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7536 && (cum->words % 2) != 0)
7543 /* Put entries into rvec[] for individual FP and vector fields, and
7544 for the chunks of memory that go in int regs. Note we start at
7545 element 1; 0 is reserved for an indication of using memory, and
7546 may or may not be filled in below. */
7547 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7548 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7550 /* If any part of the struct went on the stack put all of it there.
7551 This hack is because the generic code for
7552 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7553 parts of the struct are not at the beginning. */
7557 return NULL_RTX; /* doesn't go in registers at all */
7559 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7561 if (k > 1 || cum->use_stack)
7562 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7567 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7570 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7574 rtx rvec[GP_ARG_NUM_REG + 1];
7576 if (align_words >= GP_ARG_NUM_REG)
7579 n_units = rs6000_arg_size (mode, type);
7581 /* Optimize the simple case where the arg fits in one gpr, except in
7582 the case of BLKmode due to assign_parms assuming that registers are
7583 BITS_PER_WORD wide. */
7585 || (n_units == 1 && mode != BLKmode))
7586 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7589 if (align_words + n_units > GP_ARG_NUM_REG)
7590 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7591 using a magic NULL_RTX component.
7592 This is not strictly correct. Only some of the arg belongs in
7593 memory, not all of it. However, the normal scheme using
7594 function_arg_partial_nregs can result in unusual subregs, eg.
7595 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7596 store the whole arg to memory is often more efficient than code
7597 to store pieces, and we know that space is available in the right
7598 place for the whole arg. */
7599 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7604 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7605 rtx off = GEN_INT (i++ * 4);
7606 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7608 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7610 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7613 /* Determine where to put an argument to a function.
7614 Value is zero to push the argument on the stack,
7615 or a hard register in which to store the argument.
7617 MODE is the argument's machine mode.
7618 TYPE is the data type of the argument (as a tree).
7619 This is null for libcalls where that information may
7621 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7622 the preceding args and about the function being called. It is
7623 not modified in this routine.
7624 NAMED is nonzero if this argument is a named parameter
7625 (otherwise it is an extra parameter matching an ellipsis).
7627 On RS/6000 the first eight words of non-FP are normally in registers
7628 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7629 Under V.4, the first 8 FP args are in registers.
7631 If this is floating-point and no prototype is specified, we use
7632 both an FP and integer register (or possibly FP reg and stack). Library
7633 functions (when CALL_LIBCALL is set) always have the proper types for args,
7634 so we can pass the FP value just in one register. emit_library_function
7635 doesn't support PARALLEL anyway.
7637 Note that for args passed by reference, function_arg will be called
7638 with MODE and TYPE set to that of the pointer to the arg, not the arg
7642 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7643 tree type, int named)
7645 enum rs6000_abi abi = DEFAULT_ABI;
7647 /* Return a marker to indicate whether CR1 needs to set or clear the
7648 bit that V.4 uses to say fp args were passed in registers.
7649 Assume that we don't need the marker for software floating point,
7650 or compiler generated library calls. */
7651 if (mode == VOIDmode)
7654 && (cum->call_cookie & CALL_LIBCALL) == 0
7656 || (cum->nargs_prototype < 0
7657 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7659 /* For the SPE, we need to crxor CR6 always. */
7661 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7662 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7663 return GEN_INT (cum->call_cookie
7664 | ((cum->fregno == FP_ARG_MIN_REG)
7665 ? CALL_V4_SET_FP_ARGS
7666 : CALL_V4_CLEAR_FP_ARGS));
7669 return GEN_INT (cum->call_cookie);
7672 if (rs6000_darwin64_abi && mode == BLKmode
7673 && TREE_CODE (type) == RECORD_TYPE)
7675 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7676 if (rslt != NULL_RTX)
7678 /* Else fall through to usual handling. */
7681 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7682 if (TARGET_64BIT && ! cum->prototype)
7684 /* Vector parameters get passed in vector register
7685 and also in GPRs or memory, in absence of prototype. */
7688 align_words = (cum->words + 1) & ~1;
7690 if (align_words >= GP_ARG_NUM_REG)
7696 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7698 return gen_rtx_PARALLEL (mode,
7700 gen_rtx_EXPR_LIST (VOIDmode,
7702 gen_rtx_EXPR_LIST (VOIDmode,
7703 gen_rtx_REG (mode, cum->vregno),
7707 return gen_rtx_REG (mode, cum->vregno);
7708 else if (TARGET_ALTIVEC_ABI
7709 && (ALTIVEC_VECTOR_MODE (mode)
7710 || VSX_VECTOR_MODE (mode)
7711 || (type && TREE_CODE (type) == VECTOR_TYPE
7712 && int_size_in_bytes (type) == 16)))
7714 if (named || abi == ABI_V4)
7718 /* Vector parameters to varargs functions under AIX or Darwin
7719 get passed in memory and possibly also in GPRs. */
7720 int align, align_words, n_words;
7721 enum machine_mode part_mode;
7723 /* Vector parameters must be 16-byte aligned. This places them at
7724 2 mod 4 in terms of words in 32-bit mode, since the parameter
7725 save area starts at offset 24 from the stack. In 64-bit mode,
7726 they just have to start on an even word, since the parameter
7727 save area is 16-byte aligned. */
7729 align = (2 - cum->words) & 3;
7731 align = cum->words & 1;
7732 align_words = cum->words + align;
7734 /* Out of registers? Memory, then. */
7735 if (align_words >= GP_ARG_NUM_REG)
7738 if (TARGET_32BIT && TARGET_POWERPC64)
7739 return rs6000_mixed_function_arg (mode, type, align_words);
7741 /* The vector value goes in GPRs. Only the part of the
7742 value in GPRs is reported here. */
7744 n_words = rs6000_arg_size (mode, type);
7745 if (align_words + n_words > GP_ARG_NUM_REG)
7746 /* Fortunately, there are only two possibilities, the value
7747 is either wholly in GPRs or half in GPRs and half not. */
7750 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7753 else if (TARGET_SPE_ABI && TARGET_SPE
7754 && (SPE_VECTOR_MODE (mode)
7755 || (TARGET_E500_DOUBLE && (mode == DFmode
7758 || mode == TCmode))))
7759 return rs6000_spe_function_arg (cum, mode, type);
7761 else if (abi == ABI_V4)
7763 if (TARGET_HARD_FLOAT && TARGET_FPRS
7764 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7765 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7766 || (mode == TFmode && !TARGET_IEEEQUAD)
7767 || mode == SDmode || mode == DDmode || mode == TDmode))
7769 /* _Decimal128 must use an even/odd register pair. This assumes
7770 that the register number is odd when fregno is odd. */
7771 if (mode == TDmode && (cum->fregno % 2) == 1)
7774 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7775 <= FP_ARG_V4_MAX_REG)
7776 return gen_rtx_REG (mode, cum->fregno);
7782 int n_words = rs6000_arg_size (mode, type);
7783 int gregno = cum->sysv_gregno;
7785 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7786 (r7,r8) or (r9,r10). As does any other 2 word item such
7787 as complex int due to a historical mistake. */
7789 gregno += (1 - gregno) & 1;
7791 /* Multi-reg args are not split between registers and stack. */
7792 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7795 if (TARGET_32BIT && TARGET_POWERPC64)
7796 return rs6000_mixed_function_arg (mode, type,
7797 gregno - GP_ARG_MIN_REG);
7798 return gen_rtx_REG (mode, gregno);
7803 int align_words = rs6000_parm_start (mode, type, cum->words);
7805 /* _Decimal128 must be passed in an even/odd float register pair.
7806 This assumes that the register number is odd when fregno is odd. */
7807 if (mode == TDmode && (cum->fregno % 2) == 1)
7810 if (USE_FP_FOR_ARG_P (cum, mode, type))
7812 rtx rvec[GP_ARG_NUM_REG + 1];
7816 enum machine_mode fmode = mode;
7817 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7819 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7821 /* Currently, we only ever need one reg here because complex
7822 doubles are split. */
7823 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7824 && (fmode == TFmode || fmode == TDmode));
7826 /* Long double or _Decimal128 split over regs and memory. */
7827 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7830 /* Do we also need to pass this arg in the parameter save
7833 && (cum->nargs_prototype <= 0
7834 || (DEFAULT_ABI == ABI_AIX
7836 && align_words >= GP_ARG_NUM_REG)));
7838 if (!needs_psave && mode == fmode)
7839 return gen_rtx_REG (fmode, cum->fregno);
7844 /* Describe the part that goes in gprs or the stack.
7845 This piece must come first, before the fprs. */
7846 if (align_words < GP_ARG_NUM_REG)
7848 unsigned long n_words = rs6000_arg_size (mode, type);
7850 if (align_words + n_words > GP_ARG_NUM_REG
7851 || (TARGET_32BIT && TARGET_POWERPC64))
7853 /* If this is partially on the stack, then we only
7854 include the portion actually in registers here. */
7855 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7858 if (align_words + n_words > GP_ARG_NUM_REG)
7859 /* Not all of the arg fits in gprs. Say that it
7860 goes in memory too, using a magic NULL_RTX
7861 component. Also see comment in
7862 rs6000_mixed_function_arg for why the normal
7863 function_arg_partial_nregs scheme doesn't work
7865 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7869 r = gen_rtx_REG (rmode,
7870 GP_ARG_MIN_REG + align_words);
7871 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7872 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7874 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7878 /* The whole arg fits in gprs. */
7879 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7880 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7884 /* It's entirely in memory. */
7885 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7888 /* Describe where this piece goes in the fprs. */
7889 r = gen_rtx_REG (fmode, cum->fregno);
7890 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7892 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7894 else if (align_words < GP_ARG_NUM_REG)
7896 if (TARGET_32BIT && TARGET_POWERPC64)
7897 return rs6000_mixed_function_arg (mode, type, align_words);
7899 if (mode == BLKmode)
7902 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7909 /* For an arg passed partly in registers and partly in memory, this is
7910 the number of bytes passed in registers. For args passed entirely in
7911 registers or entirely in memory, zero. When an arg is described by a
7912 PARALLEL, perhaps using more than one register type, this function
7913 returns the number of bytes used by the first element of the PARALLEL. */
7916 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7917 tree type, bool named)
7922 if (DEFAULT_ABI == ABI_V4)
7925 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7926 && cum->nargs_prototype >= 0)
7929 /* In this complicated case we just disable the partial_nregs code. */
7930 if (rs6000_darwin64_abi && mode == BLKmode
7931 && TREE_CODE (type) == RECORD_TYPE
7932 && int_size_in_bytes (type) > 0)
7935 align_words = rs6000_parm_start (mode, type, cum->words);
7937 if (USE_FP_FOR_ARG_P (cum, mode, type))
7939 /* If we are passing this arg in the fixed parameter save area
7940 (gprs or memory) as well as fprs, then this function should
7941 return the number of partial bytes passed in the parameter
7942 save area rather than partial bytes passed in fprs. */
7944 && (cum->nargs_prototype <= 0
7945 || (DEFAULT_ABI == ABI_AIX
7947 && align_words >= GP_ARG_NUM_REG)))
7949 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7950 > FP_ARG_MAX_REG + 1)
7951 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7952 else if (cum->nargs_prototype >= 0)
7956 if (align_words < GP_ARG_NUM_REG
7957 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7958 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7960 if (ret != 0 && TARGET_DEBUG_ARG)
7961 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7966 /* A C expression that indicates when an argument must be passed by
7967 reference. If nonzero for an argument, a copy of that argument is
7968 made in memory and a pointer to the argument is passed instead of
7969 the argument itself. The pointer is passed in whatever way is
7970 appropriate for passing a pointer to that type.
7972 Under V.4, aggregates and long double are passed by reference.
7974 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7975 reference unless the AltiVec vector extension ABI is in force.
7977 As an extension to all ABIs, variable sized types are passed by
7981 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7982 enum machine_mode mode, const_tree type,
7983 bool named ATTRIBUTE_UNUSED)
7985 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7987 if (TARGET_DEBUG_ARG)
7988 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7995 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7997 if (TARGET_DEBUG_ARG)
7998 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8002 if (int_size_in_bytes (type) < 0)
8004 if (TARGET_DEBUG_ARG)
8005 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8009 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8010 modes only exist for GCC vector types if -maltivec. */
8011 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8013 if (TARGET_DEBUG_ARG)
8014 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8018 /* Pass synthetic vectors in memory. */
8019 if (TREE_CODE (type) == VECTOR_TYPE
8020 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8022 static bool warned_for_pass_big_vectors = false;
8023 if (TARGET_DEBUG_ARG)
8024 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8025 if (!warned_for_pass_big_vectors)
8027 warning (0, "GCC vector passed by reference: "
8028 "non-standard ABI extension with no compatibility guarantee");
8029 warned_for_pass_big_vectors = true;
8038 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8041 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8046 for (i = 0; i < nregs; i++)
8048 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8049 if (reload_completed)
8051 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8054 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8055 i * GET_MODE_SIZE (reg_mode));
8058 tem = replace_equiv_address (tem, XEXP (tem, 0));
8062 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8066 /* Perform any needed actions needed for a function that is receiving a
8067 variable number of arguments.
8071 MODE and TYPE are the mode and type of the current parameter.
8073 PRETEND_SIZE is a variable that should be set to the amount of stack
8074 that must be pushed by the prolog to pretend that our caller pushed
8077 Normally, this macro will push all remaining incoming registers on the
8078 stack and set PRETEND_SIZE to the length of the registers pushed. */
8081 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8082 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8085 CUMULATIVE_ARGS next_cum;
8086 int reg_size = TARGET_32BIT ? 4 : 8;
8087 rtx save_area = NULL_RTX, mem;
8088 int first_reg_offset;
8091 /* Skip the last named argument. */
8093 function_arg_advance (&next_cum, mode, type, 1, 0);
8095 if (DEFAULT_ABI == ABI_V4)
8097 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8101 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8102 HOST_WIDE_INT offset = 0;
8104 /* Try to optimize the size of the varargs save area.
8105 The ABI requires that ap.reg_save_area is doubleword
8106 aligned, but we don't need to allocate space for all
8107 the bytes, only those to which we actually will save
8109 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8110 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8111 if (TARGET_HARD_FLOAT && TARGET_FPRS
8112 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8113 && cfun->va_list_fpr_size)
8116 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8117 * UNITS_PER_FP_WORD;
8118 if (cfun->va_list_fpr_size
8119 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8120 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8122 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8123 * UNITS_PER_FP_WORD;
8127 offset = -((first_reg_offset * reg_size) & ~7);
8128 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8130 gpr_reg_num = cfun->va_list_gpr_size;
8131 if (reg_size == 4 && (first_reg_offset & 1))
8134 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8137 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8139 - (int) (GP_ARG_NUM_REG * reg_size);
8141 if (gpr_size + fpr_size)
8144 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8145 gcc_assert (GET_CODE (reg_save_area) == MEM);
8146 reg_save_area = XEXP (reg_save_area, 0);
8147 if (GET_CODE (reg_save_area) == PLUS)
8149 gcc_assert (XEXP (reg_save_area, 0)
8150 == virtual_stack_vars_rtx);
8151 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8152 offset += INTVAL (XEXP (reg_save_area, 1));
8155 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8158 cfun->machine->varargs_save_offset = offset;
8159 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8164 first_reg_offset = next_cum.words;
8165 save_area = virtual_incoming_args_rtx;
8167 if (targetm.calls.must_pass_in_stack (mode, type))
8168 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8171 set = get_varargs_alias_set ();
8172 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8173 && cfun->va_list_gpr_size)
8175 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8177 if (va_list_gpr_counter_field)
8179 /* V4 va_list_gpr_size counts number of registers needed. */
8180 if (nregs > cfun->va_list_gpr_size)
8181 nregs = cfun->va_list_gpr_size;
8185 /* char * va_list instead counts number of bytes needed. */
8186 if (nregs > cfun->va_list_gpr_size / reg_size)
8187 nregs = cfun->va_list_gpr_size / reg_size;
8190 mem = gen_rtx_MEM (BLKmode,
8191 plus_constant (save_area,
8192 first_reg_offset * reg_size));
8193 MEM_NOTRAP_P (mem) = 1;
8194 set_mem_alias_set (mem, set);
8195 set_mem_align (mem, BITS_PER_WORD);
8197 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8201 /* Save FP registers if needed. */
8202 if (DEFAULT_ABI == ABI_V4
8203 && TARGET_HARD_FLOAT && TARGET_FPRS
8205 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8206 && cfun->va_list_fpr_size)
8208 int fregno = next_cum.fregno, nregs;
8209 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8210 rtx lab = gen_label_rtx ();
8211 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8212 * UNITS_PER_FP_WORD);
8215 (gen_rtx_SET (VOIDmode,
8217 gen_rtx_IF_THEN_ELSE (VOIDmode,
8218 gen_rtx_NE (VOIDmode, cr1,
8220 gen_rtx_LABEL_REF (VOIDmode, lab),
8224 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8225 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8227 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8229 plus_constant (save_area, off));
8230 MEM_NOTRAP_P (mem) = 1;
8231 set_mem_alias_set (mem, set);
8232 set_mem_align (mem, GET_MODE_ALIGNMENT (
8233 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8234 ? DFmode : SFmode));
8235 emit_move_insn (mem, gen_rtx_REG (
8236 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8237 ? DFmode : SFmode, fregno));
8244 /* Create the va_list data type. */
8247 rs6000_build_builtin_va_list (void)
8249 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8251 /* For AIX, prefer 'char *' because that's what the system
8252 header files like. */
8253 if (DEFAULT_ABI != ABI_V4)
8254 return build_pointer_type (char_type_node);
8256 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8257 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8258 get_identifier ("__va_list_tag"), record);
8260 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8261 unsigned_char_type_node);
8262 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8263 unsigned_char_type_node);
8264 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8266 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8267 get_identifier ("reserved"), short_unsigned_type_node);
8268 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8269 get_identifier ("overflow_arg_area"),
8271 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8272 get_identifier ("reg_save_area"),
8275 va_list_gpr_counter_field = f_gpr;
8276 va_list_fpr_counter_field = f_fpr;
8278 DECL_FIELD_CONTEXT (f_gpr) = record;
8279 DECL_FIELD_CONTEXT (f_fpr) = record;
8280 DECL_FIELD_CONTEXT (f_res) = record;
8281 DECL_FIELD_CONTEXT (f_ovf) = record;
8282 DECL_FIELD_CONTEXT (f_sav) = record;
8284 TREE_CHAIN (record) = type_decl;
8285 TYPE_NAME (record) = type_decl;
8286 TYPE_FIELDS (record) = f_gpr;
8287 TREE_CHAIN (f_gpr) = f_fpr;
8288 TREE_CHAIN (f_fpr) = f_res;
8289 TREE_CHAIN (f_res) = f_ovf;
8290 TREE_CHAIN (f_ovf) = f_sav;
8292 layout_type (record);
8294 /* The correct type is an array type of one element. */
8295 return build_array_type (record, build_index_type (size_zero_node));
8298 /* Implement va_start. */
8301 rs6000_va_start (tree valist, rtx nextarg)
8303 HOST_WIDE_INT words, n_gpr, n_fpr;
8304 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8305 tree gpr, fpr, ovf, sav, t;
8307 /* Only SVR4 needs something special. */
8308 if (DEFAULT_ABI != ABI_V4)
8310 std_expand_builtin_va_start (valist, nextarg);
8314 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8315 f_fpr = TREE_CHAIN (f_gpr);
8316 f_res = TREE_CHAIN (f_fpr);
8317 f_ovf = TREE_CHAIN (f_res);
8318 f_sav = TREE_CHAIN (f_ovf);
8320 valist = build_va_arg_indirect_ref (valist);
8321 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8322 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8324 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8326 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8329 /* Count number of gp and fp argument registers used. */
8330 words = crtl->args.info.words;
8331 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8333 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8336 if (TARGET_DEBUG_ARG)
8337 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8338 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8339 words, n_gpr, n_fpr);
8341 if (cfun->va_list_gpr_size)
8343 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8344 build_int_cst (NULL_TREE, n_gpr));
8345 TREE_SIDE_EFFECTS (t) = 1;
8346 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8349 if (cfun->va_list_fpr_size)
8351 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8352 build_int_cst (NULL_TREE, n_fpr));
8353 TREE_SIDE_EFFECTS (t) = 1;
8354 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8357 /* Find the overflow area. */
8358 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8360 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8361 size_int (words * UNITS_PER_WORD));
8362 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8363 TREE_SIDE_EFFECTS (t) = 1;
8364 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8366 /* If there were no va_arg invocations, don't set up the register
8368 if (!cfun->va_list_gpr_size
8369 && !cfun->va_list_fpr_size
8370 && n_gpr < GP_ARG_NUM_REG
8371 && n_fpr < FP_ARG_V4_MAX_REG)
8374 /* Find the register save area. */
8375 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8376 if (cfun->machine->varargs_save_offset)
8377 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8378 size_int (cfun->machine->varargs_save_offset));
8379 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8380 TREE_SIDE_EFFECTS (t) = 1;
8381 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8384 /* Implement va_arg. */
8387 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8390 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8391 tree gpr, fpr, ovf, sav, reg, t, u;
8392 int size, rsize, n_reg, sav_ofs, sav_scale;
8393 tree lab_false, lab_over, addr;
8395 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8399 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8401 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8402 return build_va_arg_indirect_ref (t);
8405 if (DEFAULT_ABI != ABI_V4)
8407 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8409 tree elem_type = TREE_TYPE (type);
8410 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8411 int elem_size = GET_MODE_SIZE (elem_mode);
8413 if (elem_size < UNITS_PER_WORD)
8415 tree real_part, imag_part;
8416 gimple_seq post = NULL;
8418 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8420 /* Copy the value into a temporary, lest the formal temporary
8421 be reused out from under us. */
8422 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8423 gimple_seq_add_seq (pre_p, post);
8425 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8428 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8432 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8435 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8436 f_fpr = TREE_CHAIN (f_gpr);
8437 f_res = TREE_CHAIN (f_fpr);
8438 f_ovf = TREE_CHAIN (f_res);
8439 f_sav = TREE_CHAIN (f_ovf);
8441 valist = build_va_arg_indirect_ref (valist);
8442 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8443 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8445 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8447 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8450 size = int_size_in_bytes (type);
8451 rsize = (size + 3) / 4;
8454 if (TARGET_HARD_FLOAT && TARGET_FPRS
8455 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8456 || (TARGET_DOUBLE_FLOAT
8457 && (TYPE_MODE (type) == DFmode
8458 || TYPE_MODE (type) == TFmode
8459 || TYPE_MODE (type) == SDmode
8460 || TYPE_MODE (type) == DDmode
8461 || TYPE_MODE (type) == TDmode))))
8463 /* FP args go in FP registers, if present. */
8465 n_reg = (size + 7) / 8;
8466 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8467 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8468 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8473 /* Otherwise into GP registers. */
8482 /* Pull the value out of the saved registers.... */
8485 addr = create_tmp_var (ptr_type_node, "addr");
8487 /* AltiVec vectors never go in registers when -mabi=altivec. */
8488 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8492 lab_false = create_artificial_label (input_location);
8493 lab_over = create_artificial_label (input_location);
8495 /* Long long and SPE vectors are aligned in the registers.
8496 As are any other 2 gpr item such as complex int due to a
8497 historical mistake. */
8499 if (n_reg == 2 && reg == gpr)
8502 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8503 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8504 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8505 unshare_expr (reg), u);
8507 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8508 reg number is 0 for f1, so we want to make it odd. */
8509 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8511 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8512 build_int_cst (TREE_TYPE (reg), 1));
8513 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8516 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8517 t = build2 (GE_EXPR, boolean_type_node, u, t);
8518 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8519 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8520 gimplify_and_add (t, pre_p);
8524 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8526 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8527 build_int_cst (TREE_TYPE (reg), n_reg));
8528 u = fold_convert (sizetype, u);
8529 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8530 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8532 /* _Decimal32 varargs are located in the second word of the 64-bit
8533 FP register for 32-bit binaries. */
8534 if (!TARGET_POWERPC64
8535 && TARGET_HARD_FLOAT && TARGET_FPRS
8536 && TYPE_MODE (type) == SDmode)
8537 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8539 gimplify_assign (addr, t, pre_p);
8541 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8543 stmt = gimple_build_label (lab_false);
8544 gimple_seq_add_stmt (pre_p, stmt);
8546 if ((n_reg == 2 && !regalign) || n_reg > 2)
8548 /* Ensure that we don't find any more args in regs.
8549 Alignment has taken care of for special cases. */
8550 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8554 /* ... otherwise out of the overflow area. */
8556 /* Care for on-stack alignment if needed. */
8560 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8561 t = fold_convert (sizetype, t);
8562 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8564 t = fold_convert (TREE_TYPE (ovf), t);
8566 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8568 gimplify_assign (unshare_expr (addr), t, pre_p);
8570 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8571 gimplify_assign (unshare_expr (ovf), t, pre_p);
8575 stmt = gimple_build_label (lab_over);
8576 gimple_seq_add_stmt (pre_p, stmt);
8579 if (STRICT_ALIGNMENT
8580 && (TYPE_ALIGN (type)
8581 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8583 /* The value (of type complex double, for example) may not be
8584 aligned in memory in the saved registers, so copy via a
8585 temporary. (This is the same code as used for SPARC.) */
8586 tree tmp = create_tmp_var (type, "va_arg_tmp");
8587 tree dest_addr = build_fold_addr_expr (tmp);
8589 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8590 3, dest_addr, addr, size_int (rsize * 4));
8592 gimplify_and_add (copy, pre_p);
8596 addr = fold_convert (ptrtype, addr);
8597 return build_va_arg_indirect_ref (addr);
8603 def_builtin (int mask, const char *name, tree type, int code)
8605 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8608 if (rs6000_builtin_decls[code])
8609 fatal_error ("internal error: builtin function to %s already processed.",
8612 rs6000_builtin_decls[code] = t =
8613 add_builtin_function (name, type, code, BUILT_IN_MD,
8616 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8617 switch (builtin_classify[code])
8622 /* assume builtin can do anything. */
8623 case RS6000_BTC_MISC:
8626 /* const function, function only depends on the inputs. */
8627 case RS6000_BTC_CONST:
8628 TREE_READONLY (t) = 1;
8629 TREE_NOTHROW (t) = 1;
8632 /* pure function, function can read global memory. */
8633 case RS6000_BTC_PURE:
8634 DECL_PURE_P (t) = 1;
8635 TREE_NOTHROW (t) = 1;
8638 /* Function is a math function. If rounding mode is on, then treat
8639 the function as not reading global memory, but it can have
8640 arbitrary side effects. If it is off, then assume the function is
8641 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8642 attribute in builtin-attribute.def that is used for the math
8644 case RS6000_BTC_FP_PURE:
8645 TREE_NOTHROW (t) = 1;
8646 if (flag_rounding_math)
8648 DECL_PURE_P (t) = 1;
8649 DECL_IS_NOVOPS (t) = 1;
8652 TREE_READONLY (t) = 1;
8658 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8660 static const struct builtin_description bdesc_3arg[] =
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8669 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8670 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8671 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8672 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8673 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8674 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8675 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8676 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8677 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8678 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8683 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8684 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8685 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8686 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8687 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8688 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8689 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8690 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8691 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8692 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8693 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8694 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8695 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8696 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8698 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8699 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8700 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8701 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8702 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8703 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8704 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8705 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8706 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8707 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8709 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8712 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8714 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8715 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8716 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8717 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8719 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8720 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8721 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8722 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8727 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8728 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8729 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8730 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8731 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8732 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8733 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8734 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8735 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8736 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8738 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8739 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8740 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8741 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8742 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8743 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8744 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8745 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8746 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8747 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8749 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8750 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8751 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8752 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8753 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8754 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8755 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8756 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8757 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8759 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8760 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8761 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8762 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8763 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8764 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8765 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8767 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8768 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8769 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8770 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8771 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8772 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8773 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8774 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8775 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8778 /* DST operations: void foo (void *, const int, const char). */
8780 static const struct builtin_description bdesc_dst[] =
8782 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8783 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8784 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8785 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8793 /* Simple binary operations: VECc = foo (VECa, VECb). */
8795 static struct builtin_description bdesc_2arg[] =
8797 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8798 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8799 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8800 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8803 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8804 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8805 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8806 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8807 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8808 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8809 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8810 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8811 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8812 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8813 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8814 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8815 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8816 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8817 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8818 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8819 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8820 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8821 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8822 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8823 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8824 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8825 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8826 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8827 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8828 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8829 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8830 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8831 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8832 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8833 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8834 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8835 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8836 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8837 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8838 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8839 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8840 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8841 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8846 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8847 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8848 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8849 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8850 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8851 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8852 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8860 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8861 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8862 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8863 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8864 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8865 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8866 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8867 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8871 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8872 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8873 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8874 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8875 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8876 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8877 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8878 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8879 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8880 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8881 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8882 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8883 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8884 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8885 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8886 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8887 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8888 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8889 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8890 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8891 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8892 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8895 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8896 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8897 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8898 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8899 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8900 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8901 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8902 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8903 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8904 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8905 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8906 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8907 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8908 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8909 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8910 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8911 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8912 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8914 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8915 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8916 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8917 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8918 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8919 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8920 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8921 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8922 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8923 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8924 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8926 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8927 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8928 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8929 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8930 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8931 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8932 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8933 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8934 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8935 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8936 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8938 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8939 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8940 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8941 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8942 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8943 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8945 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8946 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8947 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8948 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8949 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8950 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8951 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8952 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8953 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8954 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8955 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8956 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8958 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8959 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8971 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8972 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8998 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8999 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9014 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9015 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9032 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9033 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9066 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9067 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9075 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9085 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9087 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9088 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9090 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9091 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9092 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9093 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9094 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9095 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9096 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9097 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9098 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9099 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9101 /* Place holder, leave as first spe builtin. */
9102 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9103 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9104 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9105 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9106 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9107 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9108 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9109 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9110 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9111 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9112 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9113 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9114 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9115 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9116 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9117 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9118 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9119 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9120 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9121 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9122 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9123 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9124 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9125 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9126 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9127 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9128 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9129 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9130 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9131 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9132 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9133 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9134 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9135 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9136 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9137 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9138 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9139 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9140 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9141 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9142 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9143 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9144 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9145 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9146 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9147 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9148 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9149 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9150 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9151 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9152 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9153 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9154 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9155 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9156 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9157 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9158 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9159 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9160 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9161 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9162 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9163 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9164 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9165 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9166 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9167 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9168 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9169 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9170 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9171 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9172 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9173 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9174 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9175 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9176 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9177 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9178 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9179 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9180 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9181 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9182 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9183 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9184 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9185 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9186 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9187 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9188 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9189 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9190 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9191 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9192 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9193 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9194 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9195 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9196 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9197 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9198 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9199 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9200 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9201 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9202 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9203 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9204 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9205 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9206 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9207 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9208 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9209 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9210 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9212 /* SPE binary operations expecting a 5-bit unsigned literal. */
9213 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9215 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9216 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9217 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9218 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9219 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9220 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9221 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9222 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9223 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9224 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9225 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9226 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9227 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9228 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9229 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9230 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9231 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9232 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9233 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9234 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9235 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9236 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9237 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9238 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9239 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9240 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9242 /* Place-holder. Leave as last binary SPE builtin. */
9243 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9246 /* AltiVec predicates. */
9248 struct builtin_description_predicates
9250 const unsigned int mask;
9251 const enum insn_code icode;
9252 const char *const name;
9253 const enum rs6000_builtins code;
9256 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9258 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9259 ALTIVEC_BUILTIN_VCMPBFP_P },
9260 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9261 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9262 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9263 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9264 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9265 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9266 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9267 ALTIVEC_BUILTIN_VCMPEQUW_P },
9268 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9269 ALTIVEC_BUILTIN_VCMPGTSW_P },
9270 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9271 ALTIVEC_BUILTIN_VCMPGTUW_P },
9272 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9273 ALTIVEC_BUILTIN_VCMPEQUH_P },
9274 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9275 ALTIVEC_BUILTIN_VCMPGTSH_P },
9276 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9277 ALTIVEC_BUILTIN_VCMPGTUH_P },
9278 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9279 ALTIVEC_BUILTIN_VCMPEQUB_P },
9280 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9281 ALTIVEC_BUILTIN_VCMPGTSB_P },
9282 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9283 ALTIVEC_BUILTIN_VCMPGTUB_P },
9285 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9286 VSX_BUILTIN_XVCMPEQSP_P },
9287 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9288 VSX_BUILTIN_XVCMPGESP_P },
9289 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9290 VSX_BUILTIN_XVCMPGTSP_P },
9291 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9292 VSX_BUILTIN_XVCMPEQDP_P },
9293 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9294 VSX_BUILTIN_XVCMPGEDP_P },
9295 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9296 VSX_BUILTIN_XVCMPGTDP_P },
9298 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9299 ALTIVEC_BUILTIN_VCMPEQ_P },
9300 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9301 ALTIVEC_BUILTIN_VCMPGT_P },
9302 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9303 ALTIVEC_BUILTIN_VCMPGE_P }
9306 /* SPE predicates. */
9307 static struct builtin_description bdesc_spe_predicates[] =
9309 /* Place-holder. Leave as first. */
9310 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9311 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9312 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9313 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9314 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9315 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9316 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9317 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9318 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9319 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9320 /* Place-holder. Leave as last. */
9321 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9324 /* SPE evsel predicates. */
9325 static struct builtin_description bdesc_spe_evsel[] =
9327 /* Place-holder. Leave as first. */
9328 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9329 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9330 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9331 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9332 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9333 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9334 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9335 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9336 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9337 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9338 /* Place-holder. Leave as last. */
9339 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9342 /* PAIRED predicates. */
9343 static const struct builtin_description bdesc_paired_preds[] =
9345 /* Place-holder. Leave as first. */
9346 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9347 /* Place-holder. Leave as last. */
9348 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9351 /* ABS* operations. */
9353 static const struct builtin_description bdesc_abs[] =
9355 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9356 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9357 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9358 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9359 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9360 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9361 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9362 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9363 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9364 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9365 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9368 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9371 static struct builtin_description bdesc_1arg[] =
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9374 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9375 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9376 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9377 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9378 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9379 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9380 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9381 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9382 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9383 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9384 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9385 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9386 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9387 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9388 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9389 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9391 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9392 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9393 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9394 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9395 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9396 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9398 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9399 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9400 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9401 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9402 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9403 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9405 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9406 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9407 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9408 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9409 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9410 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9412 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9413 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9414 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9415 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9416 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9417 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9419 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9420 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9421 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9422 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9424 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9425 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9426 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9427 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9428 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9429 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9430 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9431 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9432 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9434 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9435 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9436 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9437 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9438 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9439 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9440 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9441 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9442 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9444 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9445 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9446 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9447 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9448 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9470 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9471 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9472 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9474 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9475 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9476 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9477 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9479 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9480 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9481 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9482 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9483 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9484 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9485 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9486 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9487 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9488 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9489 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9490 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9491 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9492 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9493 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9494 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9495 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9496 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9497 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9498 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9499 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9500 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9501 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9502 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9503 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9504 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9505 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9506 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9507 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9508 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9510 /* Place-holder. Leave as last unary SPE builtin. */
9511 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9513 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9514 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9515 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9516 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9517 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9521 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9524 tree arg0 = CALL_EXPR_ARG (exp, 0);
9525 rtx op0 = expand_normal (arg0);
9526 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9527 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9529 if (icode == CODE_FOR_nothing)
9530 /* Builtin not supported on this processor. */
9533 /* If we got invalid arguments bail out before generating bad rtl. */
9534 if (arg0 == error_mark_node)
9537 if (icode == CODE_FOR_altivec_vspltisb
9538 || icode == CODE_FOR_altivec_vspltish
9539 || icode == CODE_FOR_altivec_vspltisw
9540 || icode == CODE_FOR_spe_evsplatfi
9541 || icode == CODE_FOR_spe_evsplati)
9543 /* Only allow 5-bit *signed* literals. */
9544 if (GET_CODE (op0) != CONST_INT
9545 || INTVAL (op0) > 15
9546 || INTVAL (op0) < -16)
9548 error ("argument 1 must be a 5-bit signed literal");
9554 || GET_MODE (target) != tmode
9555 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9556 target = gen_reg_rtx (tmode);
9558 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9559 op0 = copy_to_mode_reg (mode0, op0);
9561 pat = GEN_FCN (icode) (target, op0);
9570 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9572 rtx pat, scratch1, scratch2;
9573 tree arg0 = CALL_EXPR_ARG (exp, 0);
9574 rtx op0 = expand_normal (arg0);
9575 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9576 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9578 /* If we have invalid arguments, bail out before generating bad rtl. */
9579 if (arg0 == error_mark_node)
9583 || GET_MODE (target) != tmode
9584 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9585 target = gen_reg_rtx (tmode);
9587 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9588 op0 = copy_to_mode_reg (mode0, op0);
9590 scratch1 = gen_reg_rtx (mode0);
9591 scratch2 = gen_reg_rtx (mode0);
9593 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9602 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9605 tree arg0 = CALL_EXPR_ARG (exp, 0);
9606 tree arg1 = CALL_EXPR_ARG (exp, 1);
9607 rtx op0 = expand_normal (arg0);
9608 rtx op1 = expand_normal (arg1);
9609 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9610 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9611 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9613 if (icode == CODE_FOR_nothing)
9614 /* Builtin not supported on this processor. */
9617 /* If we got invalid arguments bail out before generating bad rtl. */
9618 if (arg0 == error_mark_node || arg1 == error_mark_node)
9621 if (icode == CODE_FOR_altivec_vcfux
9622 || icode == CODE_FOR_altivec_vcfsx
9623 || icode == CODE_FOR_altivec_vctsxs
9624 || icode == CODE_FOR_altivec_vctuxs
9625 || icode == CODE_FOR_altivec_vspltb
9626 || icode == CODE_FOR_altivec_vsplth
9627 || icode == CODE_FOR_altivec_vspltw
9628 || icode == CODE_FOR_spe_evaddiw
9629 || icode == CODE_FOR_spe_evldd
9630 || icode == CODE_FOR_spe_evldh
9631 || icode == CODE_FOR_spe_evldw
9632 || icode == CODE_FOR_spe_evlhhesplat
9633 || icode == CODE_FOR_spe_evlhhossplat
9634 || icode == CODE_FOR_spe_evlhhousplat
9635 || icode == CODE_FOR_spe_evlwhe
9636 || icode == CODE_FOR_spe_evlwhos
9637 || icode == CODE_FOR_spe_evlwhou
9638 || icode == CODE_FOR_spe_evlwhsplat
9639 || icode == CODE_FOR_spe_evlwwsplat
9640 || icode == CODE_FOR_spe_evrlwi
9641 || icode == CODE_FOR_spe_evslwi
9642 || icode == CODE_FOR_spe_evsrwis
9643 || icode == CODE_FOR_spe_evsubifw
9644 || icode == CODE_FOR_spe_evsrwiu)
9646 /* Only allow 5-bit unsigned literals. */
9648 if (TREE_CODE (arg1) != INTEGER_CST
9649 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9651 error ("argument 2 must be a 5-bit unsigned literal");
9657 || GET_MODE (target) != tmode
9658 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9659 target = gen_reg_rtx (tmode);
9661 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9662 op0 = copy_to_mode_reg (mode0, op0);
9663 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9664 op1 = copy_to_mode_reg (mode1, op1);
9666 pat = GEN_FCN (icode) (target, op0, op1);
9675 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9678 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9679 tree arg0 = CALL_EXPR_ARG (exp, 1);
9680 tree arg1 = CALL_EXPR_ARG (exp, 2);
9681 rtx op0 = expand_normal (arg0);
9682 rtx op1 = expand_normal (arg1);
9683 enum machine_mode tmode = SImode;
9684 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9685 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9688 if (TREE_CODE (cr6_form) != INTEGER_CST)
9690 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9694 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9696 gcc_assert (mode0 == mode1);
9698 /* If we have invalid arguments, bail out before generating bad rtl. */
9699 if (arg0 == error_mark_node || arg1 == error_mark_node)
9703 || GET_MODE (target) != tmode
9704 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9705 target = gen_reg_rtx (tmode);
9707 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9708 op0 = copy_to_mode_reg (mode0, op0);
9709 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9710 op1 = copy_to_mode_reg (mode1, op1);
9712 scratch = gen_reg_rtx (mode0);
9714 pat = GEN_FCN (icode) (scratch, op0, op1);
9719 /* The vec_any* and vec_all* predicates use the same opcodes for two
9720 different operations, but the bits in CR6 will be different
9721 depending on what information we want. So we have to play tricks
9722 with CR6 to get the right bits out.
9724 If you think this is disgusting, look at the specs for the
9725 AltiVec predicates. */
9727 switch (cr6_form_int)
9730 emit_insn (gen_cr6_test_for_zero (target));
9733 emit_insn (gen_cr6_test_for_zero_reverse (target));
9736 emit_insn (gen_cr6_test_for_lt (target));
9739 emit_insn (gen_cr6_test_for_lt_reverse (target));
9742 error ("argument 1 of __builtin_altivec_predicate is out of range");
9750 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9753 tree arg0 = CALL_EXPR_ARG (exp, 0);
9754 tree arg1 = CALL_EXPR_ARG (exp, 1);
9755 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9756 enum machine_mode mode0 = Pmode;
9757 enum machine_mode mode1 = Pmode;
9758 rtx op0 = expand_normal (arg0);
9759 rtx op1 = expand_normal (arg1);
9761 if (icode == CODE_FOR_nothing)
9762 /* Builtin not supported on this processor. */
9765 /* If we got invalid arguments bail out before generating bad rtl. */
9766 if (arg0 == error_mark_node || arg1 == error_mark_node)
9770 || GET_MODE (target) != tmode
9771 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9772 target = gen_reg_rtx (tmode);
9774 op1 = copy_to_mode_reg (mode1, op1);
9776 if (op0 == const0_rtx)
9778 addr = gen_rtx_MEM (tmode, op1);
9782 op0 = copy_to_mode_reg (mode0, op0);
9783 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9786 pat = GEN_FCN (icode) (target, addr);
9796 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9799 tree arg0 = CALL_EXPR_ARG (exp, 0);
9800 tree arg1 = CALL_EXPR_ARG (exp, 1);
9801 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9802 enum machine_mode mode0 = Pmode;
9803 enum machine_mode mode1 = Pmode;
9804 rtx op0 = expand_normal (arg0);
9805 rtx op1 = expand_normal (arg1);
9807 if (icode == CODE_FOR_nothing)
9808 /* Builtin not supported on this processor. */
9811 /* If we got invalid arguments bail out before generating bad rtl. */
9812 if (arg0 == error_mark_node || arg1 == error_mark_node)
9816 || GET_MODE (target) != tmode
9817 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9818 target = gen_reg_rtx (tmode);
9820 op1 = copy_to_mode_reg (mode1, op1);
9822 if (op0 == const0_rtx)
9824 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9828 op0 = copy_to_mode_reg (mode0, op0);
9829 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9832 pat = GEN_FCN (icode) (target, addr);
9842 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9844 tree arg0 = CALL_EXPR_ARG (exp, 0);
9845 tree arg1 = CALL_EXPR_ARG (exp, 1);
9846 tree arg2 = CALL_EXPR_ARG (exp, 2);
9847 rtx op0 = expand_normal (arg0);
9848 rtx op1 = expand_normal (arg1);
9849 rtx op2 = expand_normal (arg2);
9851 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9852 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9853 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9855 /* Invalid arguments. Bail before doing anything stoopid! */
9856 if (arg0 == error_mark_node
9857 || arg1 == error_mark_node
9858 || arg2 == error_mark_node)
9861 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9862 op0 = copy_to_mode_reg (mode2, op0);
9863 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9864 op1 = copy_to_mode_reg (mode0, op1);
9865 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9866 op2 = copy_to_mode_reg (mode1, op2);
9868 pat = GEN_FCN (icode) (op1, op2, op0);
9875 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9877 tree arg0 = CALL_EXPR_ARG (exp, 0);
9878 tree arg1 = CALL_EXPR_ARG (exp, 1);
9879 tree arg2 = CALL_EXPR_ARG (exp, 2);
9880 rtx op0 = expand_normal (arg0);
9881 rtx op1 = expand_normal (arg1);
9882 rtx op2 = expand_normal (arg2);
9884 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9885 enum machine_mode mode1 = Pmode;
9886 enum machine_mode mode2 = Pmode;
9888 /* Invalid arguments. Bail before doing anything stoopid! */
9889 if (arg0 == error_mark_node
9890 || arg1 == error_mark_node
9891 || arg2 == error_mark_node)
9894 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9895 op0 = copy_to_mode_reg (tmode, op0);
9897 op2 = copy_to_mode_reg (mode2, op2);
9899 if (op1 == const0_rtx)
9901 addr = gen_rtx_MEM (tmode, op2);
9905 op1 = copy_to_mode_reg (mode1, op1);
9906 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9909 pat = GEN_FCN (icode) (addr, op0);
9916 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9918 tree arg0 = CALL_EXPR_ARG (exp, 0);
9919 tree arg1 = CALL_EXPR_ARG (exp, 1);
9920 tree arg2 = CALL_EXPR_ARG (exp, 2);
9921 rtx op0 = expand_normal (arg0);
9922 rtx op1 = expand_normal (arg1);
9923 rtx op2 = expand_normal (arg2);
9925 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9926 enum machine_mode mode1 = Pmode;
9927 enum machine_mode mode2 = Pmode;
9929 /* Invalid arguments. Bail before doing anything stoopid! */
9930 if (arg0 == error_mark_node
9931 || arg1 == error_mark_node
9932 || arg2 == error_mark_node)
9935 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9936 op0 = copy_to_mode_reg (tmode, op0);
9938 op2 = copy_to_mode_reg (mode2, op2);
9940 if (op1 == const0_rtx)
9942 addr = gen_rtx_MEM (tmode, op2);
9946 op1 = copy_to_mode_reg (mode1, op1);
9947 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9950 pat = GEN_FCN (icode) (addr, op0);
9957 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9960 tree arg0 = CALL_EXPR_ARG (exp, 0);
9961 tree arg1 = CALL_EXPR_ARG (exp, 1);
9962 tree arg2 = CALL_EXPR_ARG (exp, 2);
9963 rtx op0 = expand_normal (arg0);
9964 rtx op1 = expand_normal (arg1);
9965 rtx op2 = expand_normal (arg2);
9966 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9967 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9968 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9969 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9971 if (icode == CODE_FOR_nothing)
9972 /* Builtin not supported on this processor. */
9975 /* If we got invalid arguments bail out before generating bad rtl. */
9976 if (arg0 == error_mark_node
9977 || arg1 == error_mark_node
9978 || arg2 == error_mark_node)
9983 case CODE_FOR_altivec_vsldoi_v4sf:
9984 case CODE_FOR_altivec_vsldoi_v4si:
9985 case CODE_FOR_altivec_vsldoi_v8hi:
9986 case CODE_FOR_altivec_vsldoi_v16qi:
9987 /* Only allow 4-bit unsigned literals. */
9989 if (TREE_CODE (arg2) != INTEGER_CST
9990 || TREE_INT_CST_LOW (arg2) & ~0xf)
9992 error ("argument 3 must be a 4-bit unsigned literal");
9997 case CODE_FOR_vsx_xxpermdi_v2df:
9998 case CODE_FOR_vsx_xxpermdi_v2di:
9999 case CODE_FOR_vsx_xxsldwi_v16qi:
10000 case CODE_FOR_vsx_xxsldwi_v8hi:
10001 case CODE_FOR_vsx_xxsldwi_v4si:
10002 case CODE_FOR_vsx_xxsldwi_v4sf:
10003 case CODE_FOR_vsx_xxsldwi_v2di:
10004 case CODE_FOR_vsx_xxsldwi_v2df:
10005 /* Only allow 2-bit unsigned literals. */
10007 if (TREE_CODE (arg2) != INTEGER_CST
10008 || TREE_INT_CST_LOW (arg2) & ~0x3)
10010 error ("argument 3 must be a 2-bit unsigned literal");
10015 case CODE_FOR_vsx_set_v2df:
10016 case CODE_FOR_vsx_set_v2di:
10017 /* Only allow 1-bit unsigned literals. */
10019 if (TREE_CODE (arg2) != INTEGER_CST
10020 || TREE_INT_CST_LOW (arg2) & ~0x1)
10022 error ("argument 3 must be a 1-bit unsigned literal");
10032 || GET_MODE (target) != tmode
10033 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10034 target = gen_reg_rtx (tmode);
10036 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10037 op0 = copy_to_mode_reg (mode0, op0);
10038 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10039 op1 = copy_to_mode_reg (mode1, op1);
10040 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10041 op2 = copy_to_mode_reg (mode2, op2);
10043 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10044 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10046 pat = GEN_FCN (icode) (target, op0, op1, op2);
10054 /* Expand the lvx builtins. */
10056 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10058 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10059 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10061 enum machine_mode tmode, mode0;
10063 enum insn_code icode;
10067 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10068 icode = CODE_FOR_vector_load_v16qi;
10070 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10071 icode = CODE_FOR_vector_load_v8hi;
10073 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10074 icode = CODE_FOR_vector_load_v4si;
10076 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10077 icode = CODE_FOR_vector_load_v4sf;
10080 *expandedp = false;
10086 arg0 = CALL_EXPR_ARG (exp, 0);
10087 op0 = expand_normal (arg0);
10088 tmode = insn_data[icode].operand[0].mode;
10089 mode0 = insn_data[icode].operand[1].mode;
10092 || GET_MODE (target) != tmode
10093 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10094 target = gen_reg_rtx (tmode);
10096 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10097 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10099 pat = GEN_FCN (icode) (target, op0);
10106 /* Expand the stvx builtins. */
10108 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10111 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10112 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10114 enum machine_mode mode0, mode1;
10116 enum insn_code icode;
10120 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10121 icode = CODE_FOR_vector_store_v16qi;
10123 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10124 icode = CODE_FOR_vector_store_v8hi;
10126 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10127 icode = CODE_FOR_vector_store_v4si;
10129 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10130 icode = CODE_FOR_vector_store_v4sf;
10133 *expandedp = false;
10137 arg0 = CALL_EXPR_ARG (exp, 0);
10138 arg1 = CALL_EXPR_ARG (exp, 1);
10139 op0 = expand_normal (arg0);
10140 op1 = expand_normal (arg1);
10141 mode0 = insn_data[icode].operand[0].mode;
10142 mode1 = insn_data[icode].operand[1].mode;
10144 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10145 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10146 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10147 op1 = copy_to_mode_reg (mode1, op1);
10149 pat = GEN_FCN (icode) (op0, op1);
10157 /* Expand the dst builtins. */
10159 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10162 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10163 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10164 tree arg0, arg1, arg2;
10165 enum machine_mode mode0, mode1, mode2;
10166 rtx pat, op0, op1, op2;
10167 const struct builtin_description *d;
10170 *expandedp = false;
10172 /* Handle DST variants. */
10174 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10175 if (d->code == fcode)
10177 arg0 = CALL_EXPR_ARG (exp, 0);
10178 arg1 = CALL_EXPR_ARG (exp, 1);
10179 arg2 = CALL_EXPR_ARG (exp, 2);
10180 op0 = expand_normal (arg0);
10181 op1 = expand_normal (arg1);
10182 op2 = expand_normal (arg2);
10183 mode0 = insn_data[d->icode].operand[0].mode;
10184 mode1 = insn_data[d->icode].operand[1].mode;
10185 mode2 = insn_data[d->icode].operand[2].mode;
10187 /* Invalid arguments, bail out before generating bad rtl. */
10188 if (arg0 == error_mark_node
10189 || arg1 == error_mark_node
10190 || arg2 == error_mark_node)
10195 if (TREE_CODE (arg2) != INTEGER_CST
10196 || TREE_INT_CST_LOW (arg2) & ~0x3)
10198 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10202 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10203 op0 = copy_to_mode_reg (Pmode, op0);
10204 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10205 op1 = copy_to_mode_reg (mode1, op1);
10207 pat = GEN_FCN (d->icode) (op0, op1, op2);
10217 /* Expand vec_init builtin. */
10219 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10221 enum machine_mode tmode = TYPE_MODE (type);
10222 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10223 int i, n_elt = GET_MODE_NUNITS (tmode);
10224 rtvec v = rtvec_alloc (n_elt);
10226 gcc_assert (VECTOR_MODE_P (tmode));
10227 gcc_assert (n_elt == call_expr_nargs (exp));
10229 for (i = 0; i < n_elt; ++i)
10231 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10232 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10235 if (!target || !register_operand (target, tmode))
10236 target = gen_reg_rtx (tmode);
10238 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10242 /* Return the integer constant in ARG. Constrain it to be in the range
10243 of the subparts of VEC_TYPE; issue an error if not. */
10246 get_element_number (tree vec_type, tree arg)
10248 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10250 if (!host_integerp (arg, 1)
10251 || (elt = tree_low_cst (arg, 1), elt > max))
10253 error ("selector must be an integer constant in the range 0..%wi", max);
10260 /* Expand vec_set builtin. */
10262 altivec_expand_vec_set_builtin (tree exp)
10264 enum machine_mode tmode, mode1;
10265 tree arg0, arg1, arg2;
10269 arg0 = CALL_EXPR_ARG (exp, 0);
10270 arg1 = CALL_EXPR_ARG (exp, 1);
10271 arg2 = CALL_EXPR_ARG (exp, 2);
10273 tmode = TYPE_MODE (TREE_TYPE (arg0));
10274 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10275 gcc_assert (VECTOR_MODE_P (tmode));
10277 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10278 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10279 elt = get_element_number (TREE_TYPE (arg0), arg2);
10281 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10282 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10284 op0 = force_reg (tmode, op0);
10285 op1 = force_reg (mode1, op1);
10287 rs6000_expand_vector_set (op0, op1, elt);
10292 /* Expand vec_ext builtin. */
10294 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10296 enum machine_mode tmode, mode0;
10301 arg0 = CALL_EXPR_ARG (exp, 0);
10302 arg1 = CALL_EXPR_ARG (exp, 1);
10304 op0 = expand_normal (arg0);
10305 elt = get_element_number (TREE_TYPE (arg0), arg1);
10307 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10308 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10309 gcc_assert (VECTOR_MODE_P (mode0));
10311 op0 = force_reg (mode0, op0);
10313 if (optimize || !target || !register_operand (target, tmode))
10314 target = gen_reg_rtx (tmode);
10316 rs6000_expand_vector_extract (target, op0, elt);
10321 /* Expand the builtin in EXP and store the result in TARGET. Store
10322 true in *EXPANDEDP if we found a builtin to expand. */
10324 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10326 const struct builtin_description *d;
10327 const struct builtin_description_predicates *dp;
10329 enum insn_code icode;
10330 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10333 enum machine_mode tmode, mode0;
10334 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10336 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10337 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10338 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10339 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10342 error ("unresolved overload for Altivec builtin %qF", fndecl);
10346 target = altivec_expand_ld_builtin (exp, target, expandedp);
10350 target = altivec_expand_st_builtin (exp, target, expandedp);
10354 target = altivec_expand_dst_builtin (exp, target, expandedp);
10362 case ALTIVEC_BUILTIN_STVX:
10363 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10364 case ALTIVEC_BUILTIN_STVEBX:
10365 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10366 case ALTIVEC_BUILTIN_STVEHX:
10367 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10368 case ALTIVEC_BUILTIN_STVEWX:
10369 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10370 case ALTIVEC_BUILTIN_STVXL:
10371 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10373 case ALTIVEC_BUILTIN_STVLX:
10374 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10375 case ALTIVEC_BUILTIN_STVLXL:
10376 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10377 case ALTIVEC_BUILTIN_STVRX:
10378 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10379 case ALTIVEC_BUILTIN_STVRXL:
10380 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10382 case ALTIVEC_BUILTIN_MFVSCR:
10383 icode = CODE_FOR_altivec_mfvscr;
10384 tmode = insn_data[icode].operand[0].mode;
10387 || GET_MODE (target) != tmode
10388 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10389 target = gen_reg_rtx (tmode);
10391 pat = GEN_FCN (icode) (target);
10397 case ALTIVEC_BUILTIN_MTVSCR:
10398 icode = CODE_FOR_altivec_mtvscr;
10399 arg0 = CALL_EXPR_ARG (exp, 0);
10400 op0 = expand_normal (arg0);
10401 mode0 = insn_data[icode].operand[0].mode;
10403 /* If we got invalid arguments bail out before generating bad rtl. */
10404 if (arg0 == error_mark_node)
10407 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10408 op0 = copy_to_mode_reg (mode0, op0);
10410 pat = GEN_FCN (icode) (op0);
10415 case ALTIVEC_BUILTIN_DSSALL:
10416 emit_insn (gen_altivec_dssall ());
10419 case ALTIVEC_BUILTIN_DSS:
10420 icode = CODE_FOR_altivec_dss;
10421 arg0 = CALL_EXPR_ARG (exp, 0);
10423 op0 = expand_normal (arg0);
10424 mode0 = insn_data[icode].operand[0].mode;
10426 /* If we got invalid arguments bail out before generating bad rtl. */
10427 if (arg0 == error_mark_node)
10430 if (TREE_CODE (arg0) != INTEGER_CST
10431 || TREE_INT_CST_LOW (arg0) & ~0x3)
10433 error ("argument to dss must be a 2-bit unsigned literal");
10437 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10438 op0 = copy_to_mode_reg (mode0, op0);
10440 emit_insn (gen_altivec_dss (op0));
10443 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10444 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10445 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10446 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10447 case VSX_BUILTIN_VEC_INIT_V2DF:
10448 case VSX_BUILTIN_VEC_INIT_V2DI:
10449 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10451 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10452 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10453 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10454 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10455 case VSX_BUILTIN_VEC_SET_V2DF:
10456 case VSX_BUILTIN_VEC_SET_V2DI:
10457 return altivec_expand_vec_set_builtin (exp);
10459 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10460 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10461 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10462 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10463 case VSX_BUILTIN_VEC_EXT_V2DF:
10464 case VSX_BUILTIN_VEC_EXT_V2DI:
10465 return altivec_expand_vec_ext_builtin (exp, target);
10469 /* Fall through. */
10472 /* Expand abs* operations. */
10474 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10475 if (d->code == fcode)
10476 return altivec_expand_abs_builtin (d->icode, exp, target);
10478 /* Expand the AltiVec predicates. */
10479 dp = bdesc_altivec_preds;
10480 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10481 if (dp->code == fcode)
10482 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10484 /* LV* are funky. We initialized them differently. */
10487 case ALTIVEC_BUILTIN_LVSL:
10488 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10489 exp, target, false);
10490 case ALTIVEC_BUILTIN_LVSR:
10491 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10492 exp, target, false);
10493 case ALTIVEC_BUILTIN_LVEBX:
10494 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10495 exp, target, false);
10496 case ALTIVEC_BUILTIN_LVEHX:
10497 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10498 exp, target, false);
10499 case ALTIVEC_BUILTIN_LVEWX:
10500 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10501 exp, target, false);
10502 case ALTIVEC_BUILTIN_LVXL:
10503 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10504 exp, target, false);
10505 case ALTIVEC_BUILTIN_LVX:
10506 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10507 exp, target, false);
10508 case ALTIVEC_BUILTIN_LVLX:
10509 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10510 exp, target, true);
10511 case ALTIVEC_BUILTIN_LVLXL:
10512 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10513 exp, target, true);
10514 case ALTIVEC_BUILTIN_LVRX:
10515 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10516 exp, target, true);
10517 case ALTIVEC_BUILTIN_LVRXL:
10518 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10519 exp, target, true);
10522 /* Fall through. */
10525 *expandedp = false;
10529 /* Expand the builtin in EXP and store the result in TARGET. Store
10530 true in *EXPANDEDP if we found a builtin to expand. */
10532 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10534 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10535 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10536 const struct builtin_description *d;
10543 case PAIRED_BUILTIN_STX:
10544 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10545 case PAIRED_BUILTIN_LX:
10546 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10549 /* Fall through. */
10552 /* Expand the paired predicates. */
10553 d = bdesc_paired_preds;
10554 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10555 if (d->code == fcode)
10556 return paired_expand_predicate_builtin (d->icode, exp, target);
10558 *expandedp = false;
10562 /* Binops that need to be initialized manually, but can be expanded
10563 automagically by rs6000_expand_binop_builtin. */
10564 static struct builtin_description bdesc_2arg_spe[] =
10566 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10567 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10568 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10569 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10570 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10571 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10572 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10573 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10574 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10575 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10576 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10577 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10578 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10579 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10580 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10581 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10582 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10583 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10584 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10585 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10586 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10587 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10590 /* Expand the builtin in EXP and store the result in TARGET. Store
10591 true in *EXPANDEDP if we found a builtin to expand.
10593 This expands the SPE builtins that are not simple unary and binary
10596 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10598 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10600 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10601 enum insn_code icode;
10602 enum machine_mode tmode, mode0;
10604 struct builtin_description *d;
10609 /* Syntax check for a 5-bit unsigned immediate. */
10612 case SPE_BUILTIN_EVSTDD:
10613 case SPE_BUILTIN_EVSTDH:
10614 case SPE_BUILTIN_EVSTDW:
10615 case SPE_BUILTIN_EVSTWHE:
10616 case SPE_BUILTIN_EVSTWHO:
10617 case SPE_BUILTIN_EVSTWWE:
10618 case SPE_BUILTIN_EVSTWWO:
10619 arg1 = CALL_EXPR_ARG (exp, 2);
10620 if (TREE_CODE (arg1) != INTEGER_CST
10621 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10623 error ("argument 2 must be a 5-bit unsigned literal");
10631 /* The evsplat*i instructions are not quite generic. */
10634 case SPE_BUILTIN_EVSPLATFI:
10635 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10637 case SPE_BUILTIN_EVSPLATI:
10638 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10644 d = (struct builtin_description *) bdesc_2arg_spe;
10645 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10646 if (d->code == fcode)
10647 return rs6000_expand_binop_builtin (d->icode, exp, target);
10649 d = (struct builtin_description *) bdesc_spe_predicates;
10650 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10651 if (d->code == fcode)
10652 return spe_expand_predicate_builtin (d->icode, exp, target);
10654 d = (struct builtin_description *) bdesc_spe_evsel;
10655 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10656 if (d->code == fcode)
10657 return spe_expand_evsel_builtin (d->icode, exp, target);
10661 case SPE_BUILTIN_EVSTDDX:
10662 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10663 case SPE_BUILTIN_EVSTDHX:
10664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10665 case SPE_BUILTIN_EVSTDWX:
10666 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10667 case SPE_BUILTIN_EVSTWHEX:
10668 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10669 case SPE_BUILTIN_EVSTWHOX:
10670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10671 case SPE_BUILTIN_EVSTWWEX:
10672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10673 case SPE_BUILTIN_EVSTWWOX:
10674 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10675 case SPE_BUILTIN_EVSTDD:
10676 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10677 case SPE_BUILTIN_EVSTDH:
10678 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10679 case SPE_BUILTIN_EVSTDW:
10680 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10681 case SPE_BUILTIN_EVSTWHE:
10682 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10683 case SPE_BUILTIN_EVSTWHO:
10684 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10685 case SPE_BUILTIN_EVSTWWE:
10686 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10687 case SPE_BUILTIN_EVSTWWO:
10688 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10689 case SPE_BUILTIN_MFSPEFSCR:
10690 icode = CODE_FOR_spe_mfspefscr;
10691 tmode = insn_data[icode].operand[0].mode;
10694 || GET_MODE (target) != tmode
10695 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10696 target = gen_reg_rtx (tmode);
10698 pat = GEN_FCN (icode) (target);
10703 case SPE_BUILTIN_MTSPEFSCR:
10704 icode = CODE_FOR_spe_mtspefscr;
10705 arg0 = CALL_EXPR_ARG (exp, 0);
10706 op0 = expand_normal (arg0);
10707 mode0 = insn_data[icode].operand[0].mode;
10709 if (arg0 == error_mark_node)
10712 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10713 op0 = copy_to_mode_reg (mode0, op0);
10715 pat = GEN_FCN (icode) (op0);
10723 *expandedp = false;
10728 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10730 rtx pat, scratch, tmp;
10731 tree form = CALL_EXPR_ARG (exp, 0);
10732 tree arg0 = CALL_EXPR_ARG (exp, 1);
10733 tree arg1 = CALL_EXPR_ARG (exp, 2);
10734 rtx op0 = expand_normal (arg0);
10735 rtx op1 = expand_normal (arg1);
10736 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10737 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10739 enum rtx_code code;
10741 if (TREE_CODE (form) != INTEGER_CST)
10743 error ("argument 1 of __builtin_paired_predicate must be a constant");
10747 form_int = TREE_INT_CST_LOW (form);
10749 gcc_assert (mode0 == mode1);
10751 if (arg0 == error_mark_node || arg1 == error_mark_node)
10755 || GET_MODE (target) != SImode
10756 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10757 target = gen_reg_rtx (SImode);
10758 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10759 op0 = copy_to_mode_reg (mode0, op0);
10760 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10761 op1 = copy_to_mode_reg (mode1, op1);
10763 scratch = gen_reg_rtx (CCFPmode);
10765 pat = GEN_FCN (icode) (scratch, op0, op1);
10787 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10790 error ("argument 1 of __builtin_paired_predicate is out of range");
10794 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10795 emit_move_insn (target, tmp);
10800 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10802 rtx pat, scratch, tmp;
10803 tree form = CALL_EXPR_ARG (exp, 0);
10804 tree arg0 = CALL_EXPR_ARG (exp, 1);
10805 tree arg1 = CALL_EXPR_ARG (exp, 2);
10806 rtx op0 = expand_normal (arg0);
10807 rtx op1 = expand_normal (arg1);
10808 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10809 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10811 enum rtx_code code;
10813 if (TREE_CODE (form) != INTEGER_CST)
10815 error ("argument 1 of __builtin_spe_predicate must be a constant");
10819 form_int = TREE_INT_CST_LOW (form);
10821 gcc_assert (mode0 == mode1);
10823 if (arg0 == error_mark_node || arg1 == error_mark_node)
10827 || GET_MODE (target) != SImode
10828 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10829 target = gen_reg_rtx (SImode);
10831 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10832 op0 = copy_to_mode_reg (mode0, op0);
10833 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10834 op1 = copy_to_mode_reg (mode1, op1);
10836 scratch = gen_reg_rtx (CCmode);
10838 pat = GEN_FCN (icode) (scratch, op0, op1);
10843 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10844 _lower_. We use one compare, but look in different bits of the
10845 CR for each variant.
10847 There are 2 elements in each SPE simd type (upper/lower). The CR
10848 bits are set as follows:
10850 BIT0 | BIT 1 | BIT 2 | BIT 3
10851 U | L | (U | L) | (U & L)
10853 So, for an "all" relationship, BIT 3 would be set.
10854 For an "any" relationship, BIT 2 would be set. Etc.
10856 Following traditional nomenclature, these bits map to:
10858 BIT0 | BIT 1 | BIT 2 | BIT 3
10861 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10866 /* All variant. OV bit. */
10868 /* We need to get to the OV bit, which is the ORDERED bit. We
10869 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10870 that's ugly and will make validate_condition_mode die.
10871 So let's just use another pattern. */
10872 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10874 /* Any variant. EQ bit. */
10878 /* Upper variant. LT bit. */
10882 /* Lower variant. GT bit. */
10887 error ("argument 1 of __builtin_spe_predicate is out of range");
10891 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10892 emit_move_insn (target, tmp);
10897 /* The evsel builtins look like this:
10899 e = __builtin_spe_evsel_OP (a, b, c, d);
10901 and work like this:
10903 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10904 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10908 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10911 tree arg0 = CALL_EXPR_ARG (exp, 0);
10912 tree arg1 = CALL_EXPR_ARG (exp, 1);
10913 tree arg2 = CALL_EXPR_ARG (exp, 2);
10914 tree arg3 = CALL_EXPR_ARG (exp, 3);
10915 rtx op0 = expand_normal (arg0);
10916 rtx op1 = expand_normal (arg1);
10917 rtx op2 = expand_normal (arg2);
10918 rtx op3 = expand_normal (arg3);
10919 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10920 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10922 gcc_assert (mode0 == mode1);
10924 if (arg0 == error_mark_node || arg1 == error_mark_node
10925 || arg2 == error_mark_node || arg3 == error_mark_node)
10929 || GET_MODE (target) != mode0
10930 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10931 target = gen_reg_rtx (mode0);
10933 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10934 op0 = copy_to_mode_reg (mode0, op0);
10935 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10936 op1 = copy_to_mode_reg (mode0, op1);
10937 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10938 op2 = copy_to_mode_reg (mode0, op2);
10939 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10940 op3 = copy_to_mode_reg (mode0, op3);
10942 /* Generate the compare. */
10943 scratch = gen_reg_rtx (CCmode);
10944 pat = GEN_FCN (icode) (scratch, op0, op1);
10949 if (mode0 == V2SImode)
10950 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10952 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10957 /* Expand an expression EXP that calls a built-in function,
10958 with result going to TARGET if that's convenient
10959 (and in mode MODE if that's convenient).
10960 SUBTARGET may be used as the target for computing one of EXP's operands.
10961 IGNORE is nonzero if the value is to be ignored. */
10964 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10965 enum machine_mode mode ATTRIBUTE_UNUSED,
10966 int ignore ATTRIBUTE_UNUSED)
10968 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10969 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10970 const struct builtin_description *d;
10975 if (fcode == RS6000_BUILTIN_RECIP)
10976 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10978 if (fcode == RS6000_BUILTIN_RECIPF)
10979 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10981 if (fcode == RS6000_BUILTIN_RSQRTF)
10982 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10984 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10985 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10987 if (fcode == POWER7_BUILTIN_BPERMD)
10988 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10989 ? CODE_FOR_bpermd_di
10990 : CODE_FOR_bpermd_si), exp, target);
10992 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10993 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10995 int icode = (int) CODE_FOR_altivec_lvsr;
10996 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10997 enum machine_mode mode = insn_data[icode].operand[1].mode;
11001 gcc_assert (TARGET_ALTIVEC);
11003 arg = CALL_EXPR_ARG (exp, 0);
11004 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
11005 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11006 addr = memory_address (mode, op);
11007 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11011 /* For the load case need to negate the address. */
11012 op = gen_reg_rtx (GET_MODE (addr));
11013 emit_insn (gen_rtx_SET (VOIDmode, op,
11014 gen_rtx_NEG (GET_MODE (addr), addr)));
11016 op = gen_rtx_MEM (mode, op);
11019 || GET_MODE (target) != tmode
11020 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11021 target = gen_reg_rtx (tmode);
11023 /*pat = gen_altivec_lvsr (target, op);*/
11024 pat = GEN_FCN (icode) (target, op);
11032 /* FIXME: There's got to be a nicer way to handle this case than
11033 constructing a new CALL_EXPR. */
11034 if (fcode == ALTIVEC_BUILTIN_VCFUX
11035 || fcode == ALTIVEC_BUILTIN_VCFSX
11036 || fcode == ALTIVEC_BUILTIN_VCTUXS
11037 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11039 if (call_expr_nargs (exp) == 1)
11040 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11041 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11044 if (TARGET_ALTIVEC)
11046 ret = altivec_expand_builtin (exp, target, &success);
11053 ret = spe_expand_builtin (exp, target, &success);
11058 if (TARGET_PAIRED_FLOAT)
11060 ret = paired_expand_builtin (exp, target, &success);
11066 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11068 /* Handle simple unary operations. */
11069 d = (struct builtin_description *) bdesc_1arg;
11070 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11071 if (d->code == fcode)
11072 return rs6000_expand_unop_builtin (d->icode, exp, target);
11074 /* Handle simple binary operations. */
11075 d = (struct builtin_description *) bdesc_2arg;
11076 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11077 if (d->code == fcode)
11078 return rs6000_expand_binop_builtin (d->icode, exp, target);
11080 /* Handle simple ternary operations. */
11082 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11083 if (d->code == fcode)
11084 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11086 gcc_unreachable ();
11090 rs6000_init_builtins (void)
11094 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11095 V2SF_type_node = build_vector_type (float_type_node, 2);
11096 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11097 V2DF_type_node = build_vector_type (double_type_node, 2);
11098 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11099 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11100 V4SF_type_node = build_vector_type (float_type_node, 4);
11101 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11102 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11104 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11105 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11106 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11107 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11109 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11110 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11111 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11112 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11114 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11115 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11116 'vector unsigned short'. */
11118 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11119 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11120 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11121 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11122 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11124 long_integer_type_internal_node = long_integer_type_node;
11125 long_unsigned_type_internal_node = long_unsigned_type_node;
11126 intQI_type_internal_node = intQI_type_node;
11127 uintQI_type_internal_node = unsigned_intQI_type_node;
11128 intHI_type_internal_node = intHI_type_node;
11129 uintHI_type_internal_node = unsigned_intHI_type_node;
11130 intSI_type_internal_node = intSI_type_node;
11131 uintSI_type_internal_node = unsigned_intSI_type_node;
11132 intDI_type_internal_node = intDI_type_node;
11133 uintDI_type_internal_node = unsigned_intDI_type_node;
11134 float_type_internal_node = float_type_node;
11135 double_type_internal_node = float_type_node;
11136 void_type_internal_node = void_type_node;
11138 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11140 builtin_mode_to_type[QImode][0] = integer_type_node;
11141 builtin_mode_to_type[HImode][0] = integer_type_node;
11142 builtin_mode_to_type[SImode][0] = intSI_type_node;
11143 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11144 builtin_mode_to_type[DImode][0] = intDI_type_node;
11145 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11146 builtin_mode_to_type[SFmode][0] = float_type_node;
11147 builtin_mode_to_type[DFmode][0] = double_type_node;
11148 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11149 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11150 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11151 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11152 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11153 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11154 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11155 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11156 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11157 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11158 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11159 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11160 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11162 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11163 get_identifier ("__bool char"),
11164 bool_char_type_node);
11165 TYPE_NAME (bool_char_type_node) = tdecl;
11166 (*lang_hooks.decls.pushdecl) (tdecl);
11167 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11168 get_identifier ("__bool short"),
11169 bool_short_type_node);
11170 TYPE_NAME (bool_short_type_node) = tdecl;
11171 (*lang_hooks.decls.pushdecl) (tdecl);
11172 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11173 get_identifier ("__bool int"),
11174 bool_int_type_node);
11175 TYPE_NAME (bool_int_type_node) = tdecl;
11176 (*lang_hooks.decls.pushdecl) (tdecl);
11177 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11179 TYPE_NAME (pixel_type_node) = tdecl;
11180 (*lang_hooks.decls.pushdecl) (tdecl);
11182 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11183 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11184 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11185 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11186 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11188 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11189 get_identifier ("__vector unsigned char"),
11190 unsigned_V16QI_type_node);
11191 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11192 (*lang_hooks.decls.pushdecl) (tdecl);
11193 tdecl = build_decl (BUILTINS_LOCATION,
11194 TYPE_DECL, get_identifier ("__vector signed char"),
11196 TYPE_NAME (V16QI_type_node) = tdecl;
11197 (*lang_hooks.decls.pushdecl) (tdecl);
11198 tdecl = build_decl (BUILTINS_LOCATION,
11199 TYPE_DECL, get_identifier ("__vector __bool char"),
11200 bool_V16QI_type_node);
11201 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11202 (*lang_hooks.decls.pushdecl) (tdecl);
11204 tdecl = build_decl (BUILTINS_LOCATION,
11205 TYPE_DECL, get_identifier ("__vector unsigned short"),
11206 unsigned_V8HI_type_node);
11207 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11208 (*lang_hooks.decls.pushdecl) (tdecl);
11209 tdecl = build_decl (BUILTINS_LOCATION,
11210 TYPE_DECL, get_identifier ("__vector signed short"),
11212 TYPE_NAME (V8HI_type_node) = tdecl;
11213 (*lang_hooks.decls.pushdecl) (tdecl);
11214 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11215 get_identifier ("__vector __bool short"),
11216 bool_V8HI_type_node);
11217 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11218 (*lang_hooks.decls.pushdecl) (tdecl);
11220 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11221 get_identifier ("__vector unsigned int"),
11222 unsigned_V4SI_type_node);
11223 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11224 (*lang_hooks.decls.pushdecl) (tdecl);
11225 tdecl = build_decl (BUILTINS_LOCATION,
11226 TYPE_DECL, get_identifier ("__vector signed int"),
11228 TYPE_NAME (V4SI_type_node) = tdecl;
11229 (*lang_hooks.decls.pushdecl) (tdecl);
11230 tdecl = build_decl (BUILTINS_LOCATION,
11231 TYPE_DECL, get_identifier ("__vector __bool int"),
11232 bool_V4SI_type_node);
11233 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11234 (*lang_hooks.decls.pushdecl) (tdecl);
11236 tdecl = build_decl (BUILTINS_LOCATION,
11237 TYPE_DECL, get_identifier ("__vector float"),
11239 TYPE_NAME (V4SF_type_node) = tdecl;
11240 (*lang_hooks.decls.pushdecl) (tdecl);
11241 tdecl = build_decl (BUILTINS_LOCATION,
11242 TYPE_DECL, get_identifier ("__vector __pixel"),
11243 pixel_V8HI_type_node);
11244 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11245 (*lang_hooks.decls.pushdecl) (tdecl);
11249 tdecl = build_decl (BUILTINS_LOCATION,
11250 TYPE_DECL, get_identifier ("__vector double"),
11252 TYPE_NAME (V2DF_type_node) = tdecl;
11253 (*lang_hooks.decls.pushdecl) (tdecl);
11255 tdecl = build_decl (BUILTINS_LOCATION,
11256 TYPE_DECL, get_identifier ("__vector long"),
11258 TYPE_NAME (V2DI_type_node) = tdecl;
11259 (*lang_hooks.decls.pushdecl) (tdecl);
11261 tdecl = build_decl (BUILTINS_LOCATION,
11262 TYPE_DECL, get_identifier ("__vector unsigned long"),
11263 unsigned_V2DI_type_node);
11264 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11265 (*lang_hooks.decls.pushdecl) (tdecl);
11267 tdecl = build_decl (BUILTINS_LOCATION,
11268 TYPE_DECL, get_identifier ("__vector __bool long"),
11269 bool_V2DI_type_node);
11270 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11271 (*lang_hooks.decls.pushdecl) (tdecl);
11274 if (TARGET_PAIRED_FLOAT)
11275 paired_init_builtins ();
11277 spe_init_builtins ();
11278 if (TARGET_ALTIVEC)
11279 altivec_init_builtins ();
11280 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11281 rs6000_common_init_builtins ();
11282 if (TARGET_PPC_GFXOPT)
11284 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11285 RS6000_BUILTIN_RECIPF,
11286 "__builtin_recipdivf");
11287 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11288 RS6000_BUILTIN_RECIPF);
11290 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11291 RS6000_BUILTIN_RSQRTF,
11292 "__builtin_rsqrtf");
11293 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11294 RS6000_BUILTIN_RSQRTF);
11296 if (TARGET_POPCNTB)
11298 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11299 RS6000_BUILTIN_RECIP,
11300 "__builtin_recipdiv");
11301 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11302 RS6000_BUILTIN_RECIP);
11305 if (TARGET_POPCNTD)
11307 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11308 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11309 POWER7_BUILTIN_BPERMD,
11310 "__builtin_bpermd");
11311 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11312 POWER7_BUILTIN_BPERMD);
11314 if (TARGET_POWERPC)
11316 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11317 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11318 unsigned_intHI_type_node,
11320 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11321 RS6000_BUILTIN_BSWAP_HI);
11325 /* AIX libm provides clog as __clog. */
11326 if (built_in_decls [BUILT_IN_CLOG])
11327 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11330 #ifdef SUBTARGET_INIT_BUILTINS
11331 SUBTARGET_INIT_BUILTINS;
11335 /* Returns the rs6000 builtin decl for CODE. */
11338 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11340 if (code >= RS6000_BUILTIN_COUNT)
11341 return error_mark_node;
11343 return rs6000_builtin_decls[code];
11346 /* Search through a set of builtins and enable the mask bits.
11347 DESC is an array of builtins.
11348 SIZE is the total number of builtins.
11349 START is the builtin enum at which to start.
11350 END is the builtin enum at which to end. */
11352 enable_mask_for_builtins (struct builtin_description *desc, int size,
11353 enum rs6000_builtins start,
11354 enum rs6000_builtins end)
11358 for (i = 0; i < size; ++i)
11359 if (desc[i].code == start)
11365 for (; i < size; ++i)
11367 /* Flip all the bits on. */
11368 desc[i].mask = target_flags;
11369 if (desc[i].code == end)
11375 spe_init_builtins (void)
11377 tree endlink = void_list_node;
11378 tree puint_type_node = build_pointer_type (unsigned_type_node);
11379 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11380 struct builtin_description *d;
11383 tree v2si_ftype_4_v2si
11384 = build_function_type
11385 (opaque_V2SI_type_node,
11386 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11387 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11388 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11389 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11392 tree v2sf_ftype_4_v2sf
11393 = build_function_type
11394 (opaque_V2SF_type_node,
11395 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11396 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11397 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11398 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11401 tree int_ftype_int_v2si_v2si
11402 = build_function_type
11403 (integer_type_node,
11404 tree_cons (NULL_TREE, integer_type_node,
11405 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11406 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11409 tree int_ftype_int_v2sf_v2sf
11410 = build_function_type
11411 (integer_type_node,
11412 tree_cons (NULL_TREE, integer_type_node,
11413 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11414 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11417 tree void_ftype_v2si_puint_int
11418 = build_function_type (void_type_node,
11419 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11420 tree_cons (NULL_TREE, puint_type_node,
11421 tree_cons (NULL_TREE,
11425 tree void_ftype_v2si_puint_char
11426 = build_function_type (void_type_node,
11427 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11428 tree_cons (NULL_TREE, puint_type_node,
11429 tree_cons (NULL_TREE,
11433 tree void_ftype_v2si_pv2si_int
11434 = build_function_type (void_type_node,
11435 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11436 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11437 tree_cons (NULL_TREE,
11441 tree void_ftype_v2si_pv2si_char
11442 = build_function_type (void_type_node,
11443 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11444 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11445 tree_cons (NULL_TREE,
11449 tree void_ftype_int
11450 = build_function_type (void_type_node,
11451 tree_cons (NULL_TREE, integer_type_node, endlink));
11453 tree int_ftype_void
11454 = build_function_type (integer_type_node, endlink);
11456 tree v2si_ftype_pv2si_int
11457 = build_function_type (opaque_V2SI_type_node,
11458 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11459 tree_cons (NULL_TREE, integer_type_node,
11462 tree v2si_ftype_puint_int
11463 = build_function_type (opaque_V2SI_type_node,
11464 tree_cons (NULL_TREE, puint_type_node,
11465 tree_cons (NULL_TREE, integer_type_node,
11468 tree v2si_ftype_pushort_int
11469 = build_function_type (opaque_V2SI_type_node,
11470 tree_cons (NULL_TREE, pushort_type_node,
11471 tree_cons (NULL_TREE, integer_type_node,
11474 tree v2si_ftype_signed_char
11475 = build_function_type (opaque_V2SI_type_node,
11476 tree_cons (NULL_TREE, signed_char_type_node,
11479 /* The initialization of the simple binary and unary builtins is
11480 done in rs6000_common_init_builtins, but we have to enable the
11481 mask bits here manually because we have run out of `target_flags'
11482 bits. We really need to redesign this mask business. */
11484 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11485 ARRAY_SIZE (bdesc_2arg),
11486 SPE_BUILTIN_EVADDW,
11487 SPE_BUILTIN_EVXOR);
11488 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11489 ARRAY_SIZE (bdesc_1arg),
11491 SPE_BUILTIN_EVSUBFUSIAAW);
11492 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11493 ARRAY_SIZE (bdesc_spe_predicates),
11494 SPE_BUILTIN_EVCMPEQ,
11495 SPE_BUILTIN_EVFSTSTLT);
11496 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11497 ARRAY_SIZE (bdesc_spe_evsel),
11498 SPE_BUILTIN_EVSEL_CMPGTS,
11499 SPE_BUILTIN_EVSEL_FSTSTEQ);
11501 (*lang_hooks.decls.pushdecl)
11502 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11503 get_identifier ("__ev64_opaque__"),
11504 opaque_V2SI_type_node));
11506 /* Initialize irregular SPE builtins. */
11508 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11509 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11510 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11511 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11512 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11513 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11514 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11515 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11516 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11517 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11518 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11519 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11520 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11521 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11522 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11523 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11524 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11525 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11528 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11529 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11530 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11531 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11532 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11533 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11534 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11535 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11536 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11537 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11538 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11539 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11540 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11541 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11542 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11543 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11544 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11545 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11546 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11547 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11548 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11549 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11552 d = (struct builtin_description *) bdesc_spe_predicates;
11553 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11557 switch (insn_data[d->icode].operand[1].mode)
11560 type = int_ftype_int_v2si_v2si;
11563 type = int_ftype_int_v2sf_v2sf;
11566 gcc_unreachable ();
11569 def_builtin (d->mask, d->name, type, d->code);
11572 /* Evsel predicates. */
11573 d = (struct builtin_description *) bdesc_spe_evsel;
11574 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11578 switch (insn_data[d->icode].operand[1].mode)
11581 type = v2si_ftype_4_v2si;
11584 type = v2sf_ftype_4_v2sf;
11587 gcc_unreachable ();
11590 def_builtin (d->mask, d->name, type, d->code);
11595 paired_init_builtins (void)
11597 const struct builtin_description *d;
11599 tree endlink = void_list_node;
11601 tree int_ftype_int_v2sf_v2sf
11602 = build_function_type
11603 (integer_type_node,
11604 tree_cons (NULL_TREE, integer_type_node,
11605 tree_cons (NULL_TREE, V2SF_type_node,
11606 tree_cons (NULL_TREE, V2SF_type_node,
11608 tree pcfloat_type_node =
11609 build_pointer_type (build_qualified_type
11610 (float_type_node, TYPE_QUAL_CONST));
11612 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11613 long_integer_type_node,
11616 tree void_ftype_v2sf_long_pcfloat =
11617 build_function_type_list (void_type_node,
11619 long_integer_type_node,
11624 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11625 PAIRED_BUILTIN_LX);
11628 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11629 PAIRED_BUILTIN_STX);
11632 d = bdesc_paired_preds;
11633 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11637 switch (insn_data[d->icode].operand[1].mode)
11640 type = int_ftype_int_v2sf_v2sf;
11643 gcc_unreachable ();
11646 def_builtin (d->mask, d->name, type, d->code);
11651 altivec_init_builtins (void)
11653 const struct builtin_description *d;
11654 const struct builtin_description_predicates *dp;
11658 tree pfloat_type_node = build_pointer_type (float_type_node);
11659 tree pint_type_node = build_pointer_type (integer_type_node);
11660 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11661 tree pchar_type_node = build_pointer_type (char_type_node);
11663 tree pvoid_type_node = build_pointer_type (void_type_node);
11665 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11666 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11667 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11668 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11670 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11672 tree int_ftype_opaque
11673 = build_function_type_list (integer_type_node,
11674 opaque_V4SI_type_node, NULL_TREE);
11675 tree opaque_ftype_opaque
11676 = build_function_type (integer_type_node,
11678 tree opaque_ftype_opaque_int
11679 = build_function_type_list (opaque_V4SI_type_node,
11680 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11681 tree opaque_ftype_opaque_opaque_int
11682 = build_function_type_list (opaque_V4SI_type_node,
11683 opaque_V4SI_type_node, opaque_V4SI_type_node,
11684 integer_type_node, NULL_TREE);
11685 tree int_ftype_int_opaque_opaque
11686 = build_function_type_list (integer_type_node,
11687 integer_type_node, opaque_V4SI_type_node,
11688 opaque_V4SI_type_node, NULL_TREE);
11689 tree int_ftype_int_v4si_v4si
11690 = build_function_type_list (integer_type_node,
11691 integer_type_node, V4SI_type_node,
11692 V4SI_type_node, NULL_TREE);
11693 tree v4sf_ftype_pcfloat
11694 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11695 tree void_ftype_pfloat_v4sf
11696 = build_function_type_list (void_type_node,
11697 pfloat_type_node, V4SF_type_node, NULL_TREE);
11698 tree v4si_ftype_pcint
11699 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11700 tree void_ftype_pint_v4si
11701 = build_function_type_list (void_type_node,
11702 pint_type_node, V4SI_type_node, NULL_TREE);
11703 tree v8hi_ftype_pcshort
11704 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11705 tree void_ftype_pshort_v8hi
11706 = build_function_type_list (void_type_node,
11707 pshort_type_node, V8HI_type_node, NULL_TREE);
11708 tree v16qi_ftype_pcchar
11709 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11710 tree void_ftype_pchar_v16qi
11711 = build_function_type_list (void_type_node,
11712 pchar_type_node, V16QI_type_node, NULL_TREE);
11713 tree void_ftype_v4si
11714 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11715 tree v8hi_ftype_void
11716 = build_function_type (V8HI_type_node, void_list_node);
11717 tree void_ftype_void
11718 = build_function_type (void_type_node, void_list_node);
11719 tree void_ftype_int
11720 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11722 tree opaque_ftype_long_pcvoid
11723 = build_function_type_list (opaque_V4SI_type_node,
11724 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11725 tree v16qi_ftype_long_pcvoid
11726 = build_function_type_list (V16QI_type_node,
11727 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11728 tree v8hi_ftype_long_pcvoid
11729 = build_function_type_list (V8HI_type_node,
11730 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11731 tree v4si_ftype_long_pcvoid
11732 = build_function_type_list (V4SI_type_node,
11733 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11735 tree void_ftype_opaque_long_pvoid
11736 = build_function_type_list (void_type_node,
11737 opaque_V4SI_type_node, long_integer_type_node,
11738 pvoid_type_node, NULL_TREE);
11739 tree void_ftype_v4si_long_pvoid
11740 = build_function_type_list (void_type_node,
11741 V4SI_type_node, long_integer_type_node,
11742 pvoid_type_node, NULL_TREE);
11743 tree void_ftype_v16qi_long_pvoid
11744 = build_function_type_list (void_type_node,
11745 V16QI_type_node, long_integer_type_node,
11746 pvoid_type_node, NULL_TREE);
11747 tree void_ftype_v8hi_long_pvoid
11748 = build_function_type_list (void_type_node,
11749 V8HI_type_node, long_integer_type_node,
11750 pvoid_type_node, NULL_TREE);
11751 tree int_ftype_int_v8hi_v8hi
11752 = build_function_type_list (integer_type_node,
11753 integer_type_node, V8HI_type_node,
11754 V8HI_type_node, NULL_TREE);
11755 tree int_ftype_int_v16qi_v16qi
11756 = build_function_type_list (integer_type_node,
11757 integer_type_node, V16QI_type_node,
11758 V16QI_type_node, NULL_TREE);
11759 tree int_ftype_int_v4sf_v4sf
11760 = build_function_type_list (integer_type_node,
11761 integer_type_node, V4SF_type_node,
11762 V4SF_type_node, NULL_TREE);
11763 tree int_ftype_int_v2df_v2df
11764 = build_function_type_list (integer_type_node,
11765 integer_type_node, V2DF_type_node,
11766 V2DF_type_node, NULL_TREE);
11767 tree v4si_ftype_v4si
11768 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11769 tree v8hi_ftype_v8hi
11770 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11771 tree v16qi_ftype_v16qi
11772 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11773 tree v4sf_ftype_v4sf
11774 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11775 tree v2df_ftype_v2df
11776 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11777 tree void_ftype_pcvoid_int_int
11778 = build_function_type_list (void_type_node,
11779 pcvoid_type_node, integer_type_node,
11780 integer_type_node, NULL_TREE);
11782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11783 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11785 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11787 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11789 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11791 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11793 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11795 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11797 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11801 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11802 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11803 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11804 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11805 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11807 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11808 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11809 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11810 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11811 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11812 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11813 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11814 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11815 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11816 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11817 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11818 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11819 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11820 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11824 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11825 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11826 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11827 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11829 if (rs6000_cpu == PROCESSOR_CELL)
11831 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11832 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11833 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11834 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11836 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11838 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11839 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11841 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11842 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11843 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11844 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11851 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11852 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11853 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11855 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11856 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11857 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11858 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11859 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11860 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11861 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11862 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11863 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11864 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11865 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11866 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11868 /* Add the DST variants. */
11870 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11871 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11873 /* Initialize the predicates. */
11874 dp = bdesc_altivec_preds;
11875 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11877 enum machine_mode mode1;
11879 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11880 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11881 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11882 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11887 mode1 = insn_data[dp->icode].operand[1].mode;
11892 type = int_ftype_int_opaque_opaque;
11895 type = int_ftype_int_v4si_v4si;
11898 type = int_ftype_int_v8hi_v8hi;
11901 type = int_ftype_int_v16qi_v16qi;
11904 type = int_ftype_int_v4sf_v4sf;
11907 type = int_ftype_int_v2df_v2df;
11910 gcc_unreachable ();
11913 def_builtin (dp->mask, dp->name, type, dp->code);
11916 /* Initialize the abs* operators. */
11918 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11920 enum machine_mode mode0;
11923 mode0 = insn_data[d->icode].operand[0].mode;
11928 type = v4si_ftype_v4si;
11931 type = v8hi_ftype_v8hi;
11934 type = v16qi_ftype_v16qi;
11937 type = v4sf_ftype_v4sf;
11940 type = v2df_ftype_v2df;
11943 gcc_unreachable ();
11946 def_builtin (d->mask, d->name, type, d->code);
11949 if (TARGET_ALTIVEC)
11953 /* Initialize target builtin that implements
11954 targetm.vectorize.builtin_mask_for_load. */
11956 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11957 v16qi_ftype_long_pcvoid,
11958 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11959 BUILT_IN_MD, NULL, NULL_TREE);
11960 TREE_READONLY (decl) = 1;
11961 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11962 altivec_builtin_mask_for_load = decl;
11965 /* Access to the vec_init patterns. */
11966 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11967 integer_type_node, integer_type_node,
11968 integer_type_node, NULL_TREE);
11969 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11970 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11972 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11973 short_integer_type_node,
11974 short_integer_type_node,
11975 short_integer_type_node,
11976 short_integer_type_node,
11977 short_integer_type_node,
11978 short_integer_type_node,
11979 short_integer_type_node, NULL_TREE);
11980 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11981 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11983 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11984 char_type_node, char_type_node,
11985 char_type_node, char_type_node,
11986 char_type_node, char_type_node,
11987 char_type_node, char_type_node,
11988 char_type_node, char_type_node,
11989 char_type_node, char_type_node,
11990 char_type_node, char_type_node,
11991 char_type_node, NULL_TREE);
11992 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11993 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11995 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11996 float_type_node, float_type_node,
11997 float_type_node, NULL_TREE);
11998 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11999 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12003 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12004 double_type_node, NULL_TREE);
12005 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12006 VSX_BUILTIN_VEC_INIT_V2DF);
12008 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12009 intDI_type_node, NULL_TREE);
12010 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12011 VSX_BUILTIN_VEC_INIT_V2DI);
12014 /* Access to the vec_set patterns. */
12015 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12017 integer_type_node, NULL_TREE);
12018 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12019 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12021 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12023 integer_type_node, NULL_TREE);
12024 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12025 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12027 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12029 integer_type_node, NULL_TREE);
12030 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12031 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12033 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12035 integer_type_node, NULL_TREE);
12036 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12037 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12041 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12043 integer_type_node, NULL_TREE);
12044 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12045 VSX_BUILTIN_VEC_SET_V2DF);
12047 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12049 integer_type_node, NULL_TREE);
12050 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12051 VSX_BUILTIN_VEC_SET_V2DI);
12054 /* Access to the vec_extract patterns. */
12055 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12056 integer_type_node, NULL_TREE);
12057 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12058 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12060 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12061 integer_type_node, NULL_TREE);
12062 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12063 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12065 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12066 integer_type_node, NULL_TREE);
12067 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12068 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12070 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12071 integer_type_node, NULL_TREE);
12072 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12073 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12077 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12078 integer_type_node, NULL_TREE);
12079 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12080 VSX_BUILTIN_VEC_EXT_V2DF);
12082 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12083 integer_type_node, NULL_TREE);
12084 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12085 VSX_BUILTIN_VEC_EXT_V2DI);
12089 /* Hash function for builtin functions with up to 3 arguments and a return
12092 builtin_hash_function (const void *hash_entry)
12096 const struct builtin_hash_struct *bh =
12097 (const struct builtin_hash_struct *) hash_entry;
12099 for (i = 0; i < 4; i++)
12101 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12102 ret = (ret * 2) + bh->uns_p[i];
12108 /* Compare builtin hash entries H1 and H2 for equivalence. */
12110 builtin_hash_eq (const void *h1, const void *h2)
12112 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12113 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12115 return ((p1->mode[0] == p2->mode[0])
12116 && (p1->mode[1] == p2->mode[1])
12117 && (p1->mode[2] == p2->mode[2])
12118 && (p1->mode[3] == p2->mode[3])
12119 && (p1->uns_p[0] == p2->uns_p[0])
12120 && (p1->uns_p[1] == p2->uns_p[1])
12121 && (p1->uns_p[2] == p2->uns_p[2])
12122 && (p1->uns_p[3] == p2->uns_p[3]));
12125 /* Map types for builtin functions with an explicit return type and up to 3
12126 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12127 of the argument. */
12129 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12130 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12131 enum rs6000_builtins builtin, const char *name)
12133 struct builtin_hash_struct h;
12134 struct builtin_hash_struct *h2;
12138 tree ret_type = NULL_TREE;
12139 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12142 /* Create builtin_hash_table. */
12143 if (builtin_hash_table == NULL)
12144 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12145 builtin_hash_eq, NULL);
12147 h.type = NULL_TREE;
12148 h.mode[0] = mode_ret;
12149 h.mode[1] = mode_arg0;
12150 h.mode[2] = mode_arg1;
12151 h.mode[3] = mode_arg2;
12157 /* If the builtin is a type that produces unsigned results or takes unsigned
12158 arguments, and it is returned as a decl for the vectorizer (such as
12159 widening multiplies, permute), make sure the arguments and return value
12160 are type correct. */
12163 /* unsigned 2 argument functions. */
12164 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12165 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12166 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12167 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12173 /* unsigned 3 argument functions. */
12174 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12175 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12176 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12177 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12178 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12179 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12180 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12181 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12182 case VSX_BUILTIN_VPERM_16QI_UNS:
12183 case VSX_BUILTIN_VPERM_8HI_UNS:
12184 case VSX_BUILTIN_VPERM_4SI_UNS:
12185 case VSX_BUILTIN_VPERM_2DI_UNS:
12186 case VSX_BUILTIN_XXSEL_16QI_UNS:
12187 case VSX_BUILTIN_XXSEL_8HI_UNS:
12188 case VSX_BUILTIN_XXSEL_4SI_UNS:
12189 case VSX_BUILTIN_XXSEL_2DI_UNS:
12196 /* signed permute functions with unsigned char mask. */
12197 case ALTIVEC_BUILTIN_VPERM_16QI:
12198 case ALTIVEC_BUILTIN_VPERM_8HI:
12199 case ALTIVEC_BUILTIN_VPERM_4SI:
12200 case ALTIVEC_BUILTIN_VPERM_4SF:
12201 case ALTIVEC_BUILTIN_VPERM_2DI:
12202 case ALTIVEC_BUILTIN_VPERM_2DF:
12203 case VSX_BUILTIN_VPERM_16QI:
12204 case VSX_BUILTIN_VPERM_8HI:
12205 case VSX_BUILTIN_VPERM_4SI:
12206 case VSX_BUILTIN_VPERM_4SF:
12207 case VSX_BUILTIN_VPERM_2DI:
12208 case VSX_BUILTIN_VPERM_2DF:
12212 /* unsigned args, signed return. */
12213 case VSX_BUILTIN_XVCVUXDDP_UNS:
12214 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12218 /* signed args, unsigned return. */
12219 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12220 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12228 /* Figure out how many args are present. */
12229 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12233 fatal_error ("internal error: builtin function %s had no type", name);
12235 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12236 if (!ret_type && h.uns_p[0])
12237 ret_type = builtin_mode_to_type[h.mode[0]][0];
12240 fatal_error ("internal error: builtin function %s had an unexpected "
12241 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12243 for (i = 0; i < num_args; i++)
12245 int m = (int) h.mode[i+1];
12246 int uns_p = h.uns_p[i+1];
12248 arg_type[i] = builtin_mode_to_type[m][uns_p];
12249 if (!arg_type[i] && uns_p)
12250 arg_type[i] = builtin_mode_to_type[m][0];
12253 fatal_error ("internal error: builtin function %s, argument %d "
12254 "had unexpected argument type %s", name, i,
12255 GET_MODE_NAME (m));
12258 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12259 if (*found == NULL)
12261 h2 = GGC_NEW (struct builtin_hash_struct);
12263 *found = (void *)h2;
12264 args = void_list_node;
12266 for (i = num_args - 1; i >= 0; i--)
12267 args = tree_cons (NULL_TREE, arg_type[i], args);
12269 h2->type = build_function_type (ret_type, args);
12272 return ((struct builtin_hash_struct *)(*found))->type;
12276 rs6000_common_init_builtins (void)
12278 const struct builtin_description *d;
12281 tree opaque_ftype_opaque = NULL_TREE;
12282 tree opaque_ftype_opaque_opaque = NULL_TREE;
12283 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12284 tree v2si_ftype_qi = NULL_TREE;
12285 tree v2si_ftype_v2si_qi = NULL_TREE;
12286 tree v2si_ftype_int_qi = NULL_TREE;
12288 if (!TARGET_PAIRED_FLOAT)
12290 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12291 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12294 /* Add the ternary operators. */
12296 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12299 int mask = d->mask;
12301 if ((mask != 0 && (mask & target_flags) == 0)
12302 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12305 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12306 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12307 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12308 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12310 if (! (type = opaque_ftype_opaque_opaque_opaque))
12311 type = opaque_ftype_opaque_opaque_opaque
12312 = build_function_type_list (opaque_V4SI_type_node,
12313 opaque_V4SI_type_node,
12314 opaque_V4SI_type_node,
12315 opaque_V4SI_type_node,
12320 enum insn_code icode = d->icode;
12321 if (d->name == 0 || icode == CODE_FOR_nothing)
12324 type = builtin_function_type (insn_data[icode].operand[0].mode,
12325 insn_data[icode].operand[1].mode,
12326 insn_data[icode].operand[2].mode,
12327 insn_data[icode].operand[3].mode,
12331 def_builtin (d->mask, d->name, type, d->code);
12334 /* Add the binary operators. */
12336 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12338 enum machine_mode mode0, mode1, mode2;
12340 int mask = d->mask;
12342 if ((mask != 0 && (mask & target_flags) == 0)
12343 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12346 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12347 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12348 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12349 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12351 if (! (type = opaque_ftype_opaque_opaque))
12352 type = opaque_ftype_opaque_opaque
12353 = build_function_type_list (opaque_V4SI_type_node,
12354 opaque_V4SI_type_node,
12355 opaque_V4SI_type_node,
12360 enum insn_code icode = d->icode;
12361 if (d->name == 0 || icode == CODE_FOR_nothing)
12364 mode0 = insn_data[icode].operand[0].mode;
12365 mode1 = insn_data[icode].operand[1].mode;
12366 mode2 = insn_data[icode].operand[2].mode;
12368 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12370 if (! (type = v2si_ftype_v2si_qi))
12371 type = v2si_ftype_v2si_qi
12372 = build_function_type_list (opaque_V2SI_type_node,
12373 opaque_V2SI_type_node,
12378 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12379 && mode2 == QImode)
12381 if (! (type = v2si_ftype_int_qi))
12382 type = v2si_ftype_int_qi
12383 = build_function_type_list (opaque_V2SI_type_node,
12390 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12394 def_builtin (d->mask, d->name, type, d->code);
12397 /* Add the simple unary operators. */
12398 d = (struct builtin_description *) bdesc_1arg;
12399 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12401 enum machine_mode mode0, mode1;
12403 int mask = d->mask;
12405 if ((mask != 0 && (mask & target_flags) == 0)
12406 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12409 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12410 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12411 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12412 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12414 if (! (type = opaque_ftype_opaque))
12415 type = opaque_ftype_opaque
12416 = build_function_type_list (opaque_V4SI_type_node,
12417 opaque_V4SI_type_node,
12422 enum insn_code icode = d->icode;
12423 if (d->name == 0 || icode == CODE_FOR_nothing)
12426 mode0 = insn_data[icode].operand[0].mode;
12427 mode1 = insn_data[icode].operand[1].mode;
12429 if (mode0 == V2SImode && mode1 == QImode)
12431 if (! (type = v2si_ftype_qi))
12432 type = v2si_ftype_qi
12433 = build_function_type_list (opaque_V2SI_type_node,
12439 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12443 def_builtin (d->mask, d->name, type, d->code);
12448 rs6000_init_libfuncs (void)
12450 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12451 && !TARGET_POWER2 && !TARGET_POWERPC)
12453 /* AIX library routines for float->int conversion. */
12454 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12455 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12456 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12457 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12460 if (!TARGET_IEEEQUAD)
12461 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12462 if (!TARGET_XL_COMPAT)
12464 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12465 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12466 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12467 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12469 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12471 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12472 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12473 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12474 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12475 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12476 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12477 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12479 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12480 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12481 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12482 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12483 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12484 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12485 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12486 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12489 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12490 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12494 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12495 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12496 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12497 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12501 /* 32-bit SVR4 quad floating point routines. */
12503 set_optab_libfunc (add_optab, TFmode, "_q_add");
12504 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12505 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12506 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12507 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12508 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12509 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12511 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12512 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12513 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12514 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12515 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12516 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12518 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12519 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12520 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12521 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12522 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12523 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12524 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12525 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12530 /* Expand a block clear operation, and return 1 if successful. Return 0
12531 if we should let the compiler generate normal code.
12533 operands[0] is the destination
12534 operands[1] is the length
12535 operands[3] is the alignment */
12538 expand_block_clear (rtx operands[])
12540 rtx orig_dest = operands[0];
12541 rtx bytes_rtx = operands[1];
12542 rtx align_rtx = operands[3];
12543 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12544 HOST_WIDE_INT align;
12545 HOST_WIDE_INT bytes;
12550 /* If this is not a fixed size move, just call memcpy */
12554 /* This must be a fixed size alignment */
12555 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12556 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12558 /* Anything to clear? */
12559 bytes = INTVAL (bytes_rtx);
12563 /* Use the builtin memset after a point, to avoid huge code bloat.
12564 When optimize_size, avoid any significant code bloat; calling
12565 memset is about 4 instructions, so allow for one instruction to
12566 load zero and three to do clearing. */
12567 if (TARGET_ALTIVEC && align >= 128)
12569 else if (TARGET_POWERPC64 && align >= 32)
12571 else if (TARGET_SPE && align >= 64)
12576 if (optimize_size && bytes > 3 * clear_step)
12578 if (! optimize_size && bytes > 8 * clear_step)
12581 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12583 enum machine_mode mode = BLKmode;
12586 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12591 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12596 else if (bytes >= 8 && TARGET_POWERPC64
12597 /* 64-bit loads and stores require word-aligned
12599 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12604 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12605 { /* move 4 bytes */
12609 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12610 { /* move 2 bytes */
12614 else /* move 1 byte at a time */
12620 dest = adjust_address (orig_dest, mode, offset);
12622 emit_move_insn (dest, CONST0_RTX (mode));
12629 /* Expand a block move operation, and return 1 if successful. Return 0
12630 if we should let the compiler generate normal code.
12632 operands[0] is the destination
12633 operands[1] is the source
12634 operands[2] is the length
12635 operands[3] is the alignment */
12637 #define MAX_MOVE_REG 4
12640 expand_block_move (rtx operands[])
12642 rtx orig_dest = operands[0];
12643 rtx orig_src = operands[1];
12644 rtx bytes_rtx = operands[2];
12645 rtx align_rtx = operands[3];
12646 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12651 rtx stores[MAX_MOVE_REG];
12654 /* If this is not a fixed size move, just call memcpy */
12658 /* This must be a fixed size alignment */
12659 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12660 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12662 /* Anything to move? */
12663 bytes = INTVAL (bytes_rtx);
12667 /* store_one_arg depends on expand_block_move to handle at least the size of
12668 reg_parm_stack_space. */
12669 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12672 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12675 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12676 rtx (*mov) (rtx, rtx);
12678 enum machine_mode mode = BLKmode;
12681 /* Altivec first, since it will be faster than a string move
12682 when it applies, and usually not significantly larger. */
12683 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12687 gen_func.mov = gen_movv4si;
12689 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12693 gen_func.mov = gen_movv2si;
12695 else if (TARGET_STRING
12696 && bytes > 24 /* move up to 32 bytes at a time */
12702 && ! fixed_regs[10]
12703 && ! fixed_regs[11]
12704 && ! fixed_regs[12])
12706 move_bytes = (bytes > 32) ? 32 : bytes;
12707 gen_func.movmemsi = gen_movmemsi_8reg;
12709 else if (TARGET_STRING
12710 && bytes > 16 /* move up to 24 bytes at a time */
12716 && ! fixed_regs[10])
12718 move_bytes = (bytes > 24) ? 24 : bytes;
12719 gen_func.movmemsi = gen_movmemsi_6reg;
12721 else if (TARGET_STRING
12722 && bytes > 8 /* move up to 16 bytes at a time */
12726 && ! fixed_regs[8])
12728 move_bytes = (bytes > 16) ? 16 : bytes;
12729 gen_func.movmemsi = gen_movmemsi_4reg;
12731 else if (bytes >= 8 && TARGET_POWERPC64
12732 /* 64-bit loads and stores require word-aligned
12734 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12738 gen_func.mov = gen_movdi;
12740 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12741 { /* move up to 8 bytes at a time */
12742 move_bytes = (bytes > 8) ? 8 : bytes;
12743 gen_func.movmemsi = gen_movmemsi_2reg;
12745 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12746 { /* move 4 bytes */
12749 gen_func.mov = gen_movsi;
12751 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12752 { /* move 2 bytes */
12755 gen_func.mov = gen_movhi;
12757 else if (TARGET_STRING && bytes > 1)
12758 { /* move up to 4 bytes at a time */
12759 move_bytes = (bytes > 4) ? 4 : bytes;
12760 gen_func.movmemsi = gen_movmemsi_1reg;
12762 else /* move 1 byte at a time */
12766 gen_func.mov = gen_movqi;
12769 src = adjust_address (orig_src, mode, offset);
12770 dest = adjust_address (orig_dest, mode, offset);
12772 if (mode != BLKmode)
12774 rtx tmp_reg = gen_reg_rtx (mode);
12776 emit_insn ((*gen_func.mov) (tmp_reg, src));
12777 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12780 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12783 for (i = 0; i < num_reg; i++)
12784 emit_insn (stores[i]);
12788 if (mode == BLKmode)
12790 /* Move the address into scratch registers. The movmemsi
12791 patterns require zero offset. */
12792 if (!REG_P (XEXP (src, 0)))
12794 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12795 src = replace_equiv_address (src, src_reg);
12797 set_mem_size (src, GEN_INT (move_bytes));
12799 if (!REG_P (XEXP (dest, 0)))
12801 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12802 dest = replace_equiv_address (dest, dest_reg);
12804 set_mem_size (dest, GEN_INT (move_bytes));
12806 emit_insn ((*gen_func.movmemsi) (dest, src,
12807 GEN_INT (move_bytes & 31),
12816 /* Return a string to perform a load_multiple operation.
12817 operands[0] is the vector.
12818 operands[1] is the source address.
12819 operands[2] is the first destination register. */
12822 rs6000_output_load_multiple (rtx operands[3])
12824 /* We have to handle the case where the pseudo used to contain the address
12825 is assigned to one of the output registers. */
12827 int words = XVECLEN (operands[0], 0);
12830 if (XVECLEN (operands[0], 0) == 1)
12831 return "{l|lwz} %2,0(%1)";
12833 for (i = 0; i < words; i++)
12834 if (refers_to_regno_p (REGNO (operands[2]) + i,
12835 REGNO (operands[2]) + i + 1, operands[1], 0))
12839 xop[0] = GEN_INT (4 * (words-1));
12840 xop[1] = operands[1];
12841 xop[2] = operands[2];
12842 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12847 xop[0] = GEN_INT (4 * (words-1));
12848 xop[1] = operands[1];
12849 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12850 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);
12855 for (j = 0; j < words; j++)
12858 xop[0] = GEN_INT (j * 4);
12859 xop[1] = operands[1];
12860 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12861 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12863 xop[0] = GEN_INT (i * 4);
12864 xop[1] = operands[1];
12865 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12870 return "{lsi|lswi} %2,%1,%N0";
12874 /* A validation routine: say whether CODE, a condition code, and MODE
12875 match. The other alternatives either don't make sense or should
12876 never be generated. */
12879 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12881 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12882 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12883 && GET_MODE_CLASS (mode) == MODE_CC);
12885 /* These don't make sense. */
12886 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12887 || mode != CCUNSmode);
12889 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12890 || mode == CCUNSmode);
12892 gcc_assert (mode == CCFPmode
12893 || (code != ORDERED && code != UNORDERED
12894 && code != UNEQ && code != LTGT
12895 && code != UNGT && code != UNLT
12896 && code != UNGE && code != UNLE));
12898 /* These should never be generated except for
12899 flag_finite_math_only. */
12900 gcc_assert (mode != CCFPmode
12901 || flag_finite_math_only
12902 || (code != LE && code != GE
12903 && code != UNEQ && code != LTGT
12904 && code != UNGT && code != UNLT));
12906 /* These are invalid; the information is not there. */
12907 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12911 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12912 mask required to convert the result of a rotate insn into a shift
12913 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12916 includes_lshift_p (rtx shiftop, rtx andop)
12918 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12920 shift_mask <<= INTVAL (shiftop);
12922 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12925 /* Similar, but for right shift. */
12928 includes_rshift_p (rtx shiftop, rtx andop)
12930 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12932 shift_mask >>= INTVAL (shiftop);
12934 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12937 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12938 to perform a left shift. It must have exactly SHIFTOP least
12939 significant 0's, then one or more 1's, then zero or more 0's. */
12942 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12944 if (GET_CODE (andop) == CONST_INT)
12946 HOST_WIDE_INT c, lsb, shift_mask;
12948 c = INTVAL (andop);
12949 if (c == 0 || c == ~0)
12953 shift_mask <<= INTVAL (shiftop);
12955 /* Find the least significant one bit. */
12958 /* It must coincide with the LSB of the shift mask. */
12959 if (-lsb != shift_mask)
12962 /* Invert to look for the next transition (if any). */
12965 /* Remove the low group of ones (originally low group of zeros). */
12968 /* Again find the lsb, and check we have all 1's above. */
12972 else if (GET_CODE (andop) == CONST_DOUBLE
12973 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12975 HOST_WIDE_INT low, high, lsb;
12976 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12978 low = CONST_DOUBLE_LOW (andop);
12979 if (HOST_BITS_PER_WIDE_INT < 64)
12980 high = CONST_DOUBLE_HIGH (andop);
12982 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12983 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12986 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12988 shift_mask_high = ~0;
12989 if (INTVAL (shiftop) > 32)
12990 shift_mask_high <<= INTVAL (shiftop) - 32;
12992 lsb = high & -high;
12994 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13000 lsb = high & -high;
13001 return high == -lsb;
13004 shift_mask_low = ~0;
13005 shift_mask_low <<= INTVAL (shiftop);
13009 if (-lsb != shift_mask_low)
13012 if (HOST_BITS_PER_WIDE_INT < 64)
13017 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13019 lsb = high & -high;
13020 return high == -lsb;
13024 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13030 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13031 to perform a left shift. It must have SHIFTOP or more least
13032 significant 0's, with the remainder of the word 1's. */
13035 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13037 if (GET_CODE (andop) == CONST_INT)
13039 HOST_WIDE_INT c, lsb, shift_mask;
13042 shift_mask <<= INTVAL (shiftop);
13043 c = INTVAL (andop);
13045 /* Find the least significant one bit. */
13048 /* It must be covered by the shift mask.
13049 This test also rejects c == 0. */
13050 if ((lsb & shift_mask) == 0)
13053 /* Check we have all 1's above the transition, and reject all 1's. */
13054 return c == -lsb && lsb != 1;
13056 else if (GET_CODE (andop) == CONST_DOUBLE
13057 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13059 HOST_WIDE_INT low, lsb, shift_mask_low;
13061 low = CONST_DOUBLE_LOW (andop);
13063 if (HOST_BITS_PER_WIDE_INT < 64)
13065 HOST_WIDE_INT high, shift_mask_high;
13067 high = CONST_DOUBLE_HIGH (andop);
13071 shift_mask_high = ~0;
13072 if (INTVAL (shiftop) > 32)
13073 shift_mask_high <<= INTVAL (shiftop) - 32;
13075 lsb = high & -high;
13077 if ((lsb & shift_mask_high) == 0)
13080 return high == -lsb;
13086 shift_mask_low = ~0;
13087 shift_mask_low <<= INTVAL (shiftop);
13091 if ((lsb & shift_mask_low) == 0)
13094 return low == -lsb && lsb != 1;
13100 /* Return 1 if operands will generate a valid arguments to rlwimi
13101 instruction for insert with right shift in 64-bit mode. The mask may
13102 not start on the first bit or stop on the last bit because wrap-around
13103 effects of instruction do not correspond to semantics of RTL insn. */
13106 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13108 if (INTVAL (startop) > 32
13109 && INTVAL (startop) < 64
13110 && INTVAL (sizeop) > 1
13111 && INTVAL (sizeop) + INTVAL (startop) < 64
13112 && INTVAL (shiftop) > 0
13113 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13114 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13120 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13121 for lfq and stfq insns iff the registers are hard registers. */
13124 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13126 /* We might have been passed a SUBREG. */
13127 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13130 /* We might have been passed non floating point registers. */
13131 if (!FP_REGNO_P (REGNO (reg1))
13132 || !FP_REGNO_P (REGNO (reg2)))
13135 return (REGNO (reg1) == REGNO (reg2) - 1);
13138 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13139 addr1 and addr2 must be in consecutive memory locations
13140 (addr2 == addr1 + 8). */
13143 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13146 unsigned int reg1, reg2;
13147 int offset1, offset2;
13149 /* The mems cannot be volatile. */
13150 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13153 addr1 = XEXP (mem1, 0);
13154 addr2 = XEXP (mem2, 0);
13156 /* Extract an offset (if used) from the first addr. */
13157 if (GET_CODE (addr1) == PLUS)
13159 /* If not a REG, return zero. */
13160 if (GET_CODE (XEXP (addr1, 0)) != REG)
13164 reg1 = REGNO (XEXP (addr1, 0));
13165 /* The offset must be constant! */
13166 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13168 offset1 = INTVAL (XEXP (addr1, 1));
13171 else if (GET_CODE (addr1) != REG)
13175 reg1 = REGNO (addr1);
13176 /* This was a simple (mem (reg)) expression. Offset is 0. */
13180 /* And now for the second addr. */
13181 if (GET_CODE (addr2) == PLUS)
13183 /* If not a REG, return zero. */
13184 if (GET_CODE (XEXP (addr2, 0)) != REG)
13188 reg2 = REGNO (XEXP (addr2, 0));
13189 /* The offset must be constant. */
13190 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13192 offset2 = INTVAL (XEXP (addr2, 1));
13195 else if (GET_CODE (addr2) != REG)
13199 reg2 = REGNO (addr2);
13200 /* This was a simple (mem (reg)) expression. Offset is 0. */
13204 /* Both of these must have the same base register. */
13208 /* The offset for the second addr must be 8 more than the first addr. */
13209 if (offset2 != offset1 + 8)
13212 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13219 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13221 static bool eliminated = false;
13224 if (mode != SDmode)
13225 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13228 rtx mem = cfun->machine->sdmode_stack_slot;
13229 gcc_assert (mem != NULL_RTX);
13233 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13234 cfun->machine->sdmode_stack_slot = mem;
13240 if (TARGET_DEBUG_ADDR)
13242 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13243 GET_MODE_NAME (mode));
13245 fprintf (stderr, "\tNULL_RTX\n");
13254 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13256 /* Don't walk into types. */
13257 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13259 *walk_subtrees = 0;
13263 switch (TREE_CODE (*tp))
13272 case ALIGN_INDIRECT_REF:
13273 case MISALIGNED_INDIRECT_REF:
13274 case VIEW_CONVERT_EXPR:
13275 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13285 enum reload_reg_type {
13287 VECTOR_REGISTER_TYPE,
13288 OTHER_REGISTER_TYPE
13291 static enum reload_reg_type
13292 rs6000_reload_register_type (enum reg_class rclass)
13298 return GPR_REGISTER_TYPE;
13303 return VECTOR_REGISTER_TYPE;
13306 return OTHER_REGISTER_TYPE;
13310 /* Inform reload about cases where moving X with a mode MODE to a register in
13311 RCLASS requires an extra scratch or immediate register. Return the class
13312 needed for the immediate register.
13314 For VSX and Altivec, we may need a register to convert sp+offset into
13317 static enum reg_class
13318 rs6000_secondary_reload (bool in_p,
13320 enum reg_class rclass,
13321 enum machine_mode mode,
13322 secondary_reload_info *sri)
13324 enum reg_class ret = ALL_REGS;
13325 enum insn_code icode;
13326 bool default_p = false;
13328 sri->icode = CODE_FOR_nothing;
13330 /* Convert vector loads and stores into gprs to use an additional base
13332 icode = rs6000_vector_reload[mode][in_p != false];
13333 if (icode != CODE_FOR_nothing)
13336 sri->icode = CODE_FOR_nothing;
13337 sri->extra_cost = 0;
13339 if (GET_CODE (x) == MEM)
13341 rtx addr = XEXP (x, 0);
13343 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13344 an extra register in that case, but it would need an extra
13345 register if the addressing is reg+reg or (reg+reg)&(-16). */
13346 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13348 if (!legitimate_indirect_address_p (addr, false)
13349 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13351 sri->icode = icode;
13352 /* account for splitting the loads, and converting the
13353 address from reg+reg to reg. */
13354 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13355 + ((GET_CODE (addr) == AND) ? 1 : 0));
13358 /* Loads to and stores from vector registers can only do reg+reg
13359 addressing. Altivec registers can also do (reg+reg)&(-16). */
13360 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13361 || rclass == FLOAT_REGS || rclass == NO_REGS)
13363 if (!VECTOR_MEM_ALTIVEC_P (mode)
13364 && GET_CODE (addr) == AND
13365 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13366 && INTVAL (XEXP (addr, 1)) == -16
13367 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13368 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13370 sri->icode = icode;
13371 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13374 else if (!legitimate_indirect_address_p (addr, false)
13375 && (rclass == NO_REGS
13376 || !legitimate_indexed_address_p (addr, false)))
13378 sri->icode = icode;
13379 sri->extra_cost = 1;
13382 icode = CODE_FOR_nothing;
13384 /* Any other loads, including to pseudo registers which haven't been
13385 assigned to a register yet, default to require a scratch
13389 sri->icode = icode;
13390 sri->extra_cost = 2;
13393 else if (REG_P (x))
13395 int regno = true_regnum (x);
13397 icode = CODE_FOR_nothing;
13398 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13402 enum reg_class xclass = REGNO_REG_CLASS (regno);
13403 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13404 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13406 /* If memory is needed, use default_secondary_reload to create the
13408 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13421 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13423 gcc_assert (ret != ALL_REGS);
13425 if (TARGET_DEBUG_ADDR)
13428 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13430 reg_class_names[ret],
13431 in_p ? "true" : "false",
13432 reg_class_names[rclass],
13433 GET_MODE_NAME (mode));
13436 fprintf (stderr, ", default secondary reload");
13438 if (sri->icode != CODE_FOR_nothing)
13439 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13440 insn_data[sri->icode].name, sri->extra_cost);
13442 fprintf (stderr, "\n");
13450 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13451 to SP+reg addressing. */
13454 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13456 int regno = true_regnum (reg);
13457 enum machine_mode mode = GET_MODE (reg);
13458 enum reg_class rclass;
13460 rtx and_op2 = NULL_RTX;
13463 rtx scratch_or_premodify = scratch;
13467 if (TARGET_DEBUG_ADDR)
13469 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13470 store_p ? "store" : "load");
13471 fprintf (stderr, "reg:\n");
13473 fprintf (stderr, "mem:\n");
13475 fprintf (stderr, "scratch:\n");
13476 debug_rtx (scratch);
13479 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13480 gcc_assert (GET_CODE (mem) == MEM);
13481 rclass = REGNO_REG_CLASS (regno);
13482 addr = XEXP (mem, 0);
13486 /* GPRs can handle reg + small constant, all other addresses need to use
13487 the scratch register. */
13490 if (GET_CODE (addr) == AND)
13492 and_op2 = XEXP (addr, 1);
13493 addr = XEXP (addr, 0);
13496 if (GET_CODE (addr) == PRE_MODIFY)
13498 scratch_or_premodify = XEXP (addr, 0);
13499 gcc_assert (REG_P (scratch_or_premodify));
13500 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13501 addr = XEXP (addr, 1);
13504 if (GET_CODE (addr) == PLUS
13505 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13506 || and_op2 != NULL_RTX))
13508 addr_op1 = XEXP (addr, 0);
13509 addr_op2 = XEXP (addr, 1);
13510 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13512 if (!REG_P (addr_op2)
13513 && (GET_CODE (addr_op2) != CONST_INT
13514 || !satisfies_constraint_I (addr_op2)))
13516 if (TARGET_DEBUG_ADDR)
13519 "\nMove plus addr to register %s, mode = %s: ",
13520 rs6000_reg_names[REGNO (scratch)],
13521 GET_MODE_NAME (mode));
13522 debug_rtx (addr_op2);
13524 rs6000_emit_move (scratch, addr_op2, Pmode);
13525 addr_op2 = scratch;
13528 emit_insn (gen_rtx_SET (VOIDmode,
13529 scratch_or_premodify,
13530 gen_rtx_PLUS (Pmode,
13534 addr = scratch_or_premodify;
13535 scratch_or_premodify = scratch;
13537 else if (!legitimate_indirect_address_p (addr, false)
13538 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13540 if (TARGET_DEBUG_ADDR)
13542 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13543 rs6000_reg_names[REGNO (scratch_or_premodify)],
13544 GET_MODE_NAME (mode));
13547 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13548 addr = scratch_or_premodify;
13549 scratch_or_premodify = scratch;
13553 /* Float/Altivec registers can only handle reg+reg addressing. Move
13554 other addresses into a scratch register. */
13559 /* With float regs, we need to handle the AND ourselves, since we can't
13560 use the Altivec instruction with an implicit AND -16. Allow scalar
13561 loads to float registers to use reg+offset even if VSX. */
13562 if (GET_CODE (addr) == AND
13563 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13564 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13565 || INTVAL (XEXP (addr, 1)) != -16
13566 || !VECTOR_MEM_ALTIVEC_P (mode)))
13568 and_op2 = XEXP (addr, 1);
13569 addr = XEXP (addr, 0);
13572 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13573 as the address later. */
13574 if (GET_CODE (addr) == PRE_MODIFY
13575 && (!VECTOR_MEM_VSX_P (mode)
13576 || and_op2 != NULL_RTX
13577 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13579 scratch_or_premodify = XEXP (addr, 0);
13580 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13582 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13583 addr = XEXP (addr, 1);
13586 if (legitimate_indirect_address_p (addr, false) /* reg */
13587 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13588 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13589 || (GET_CODE (addr) == AND /* Altivec memory */
13590 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13591 && INTVAL (XEXP (addr, 1)) == -16
13592 && VECTOR_MEM_ALTIVEC_P (mode))
13593 || (rclass == FLOAT_REGS /* legacy float mem */
13594 && GET_MODE_SIZE (mode) == 8
13595 && and_op2 == NULL_RTX
13596 && scratch_or_premodify == scratch
13597 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13600 else if (GET_CODE (addr) == PLUS)
13602 addr_op1 = XEXP (addr, 0);
13603 addr_op2 = XEXP (addr, 1);
13604 gcc_assert (REG_P (addr_op1));
13606 if (TARGET_DEBUG_ADDR)
13608 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13609 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13610 debug_rtx (addr_op2);
13612 rs6000_emit_move (scratch, addr_op2, Pmode);
13613 emit_insn (gen_rtx_SET (VOIDmode,
13614 scratch_or_premodify,
13615 gen_rtx_PLUS (Pmode,
13618 addr = scratch_or_premodify;
13619 scratch_or_premodify = scratch;
13622 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13623 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13625 if (TARGET_DEBUG_ADDR)
13627 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13628 rs6000_reg_names[REGNO (scratch_or_premodify)],
13629 GET_MODE_NAME (mode));
13633 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13634 addr = scratch_or_premodify;
13635 scratch_or_premodify = scratch;
13639 gcc_unreachable ();
13644 gcc_unreachable ();
13647 /* If the original address involved a pre-modify that we couldn't use the VSX
13648 memory instruction with update, and we haven't taken care of already,
13649 store the address in the pre-modify register and use that as the
13651 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13653 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13654 addr = scratch_or_premodify;
13657 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13658 memory instruction, recreate the AND now, including the clobber which is
13659 generated by the general ANDSI3/ANDDI3 patterns for the
13660 andi. instruction. */
13661 if (and_op2 != NULL_RTX)
13663 if (! legitimate_indirect_address_p (addr, false))
13665 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13669 if (TARGET_DEBUG_ADDR)
13671 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13672 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13673 debug_rtx (and_op2);
13676 and_rtx = gen_rtx_SET (VOIDmode,
13678 gen_rtx_AND (Pmode,
13682 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13683 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13684 gen_rtvec (2, and_rtx, cc_clobber)));
13688 /* Adjust the address if it changed. */
13689 if (addr != XEXP (mem, 0))
13691 mem = change_address (mem, mode, addr);
13692 if (TARGET_DEBUG_ADDR)
13693 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13696 /* Now create the move. */
13698 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13700 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13705 /* Target hook to return the cover classes for Integrated Register Allocator.
13706 Cover classes is a set of non-intersected register classes covering all hard
13707 registers used for register allocation purpose. Any move between two
13708 registers of a cover class should be cheaper than load or store of the
13709 registers. The value is array of register classes with LIM_REG_CLASSES used
13712 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13713 account for the Altivec and Floating registers being subsets of the VSX
13714 register set under VSX, but distinct register sets on pre-VSX machines. */
13716 static const enum reg_class *
13717 rs6000_ira_cover_classes (void)
13719 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13720 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13722 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13725 /* Allocate a 64-bit stack slot to be used for copying SDmode
13726 values through if this function has any SDmode references. */
13729 rs6000_alloc_sdmode_stack_slot (void)
13733 gimple_stmt_iterator gsi;
13735 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13738 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13740 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13743 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13744 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13750 /* Check for any SDmode parameters of the function. */
13751 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13753 if (TREE_TYPE (t) == error_mark_node)
13756 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13757 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13759 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13760 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13768 rs6000_instantiate_decls (void)
13770 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13771 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13774 /* Given an rtx X being reloaded into a reg required to be
13775 in class CLASS, return the class of reg to actually use.
13776 In general this is just CLASS; but on some machines
13777 in some cases it is preferable to use a more restrictive class.
13779 On the RS/6000, we have to return NO_REGS when we want to reload a
13780 floating-point CONST_DOUBLE to force it to be copied to memory.
13782 We also don't want to reload integer values into floating-point
13783 registers if we can at all help it. In fact, this can
13784 cause reload to die, if it tries to generate a reload of CTR
13785 into a FP register and discovers it doesn't have the memory location
13788 ??? Would it be a good idea to have reload do the converse, that is
13789 try to reload floating modes into FP registers if possible?
13792 static enum reg_class
13793 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13795 enum machine_mode mode = GET_MODE (x);
13797 if (VECTOR_UNIT_VSX_P (mode)
13798 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13801 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13802 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13803 && easy_vector_constant (x, mode))
13804 return ALTIVEC_REGS;
13806 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13809 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13810 return GENERAL_REGS;
13812 /* For VSX, prefer the traditional registers for DF if the address is of the
13813 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13814 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13816 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13818 if (mode == DFmode && GET_CODE (x) == MEM)
13820 rtx addr = XEXP (x, 0);
13822 if (legitimate_indirect_address_p (addr, false)) /* reg */
13825 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13828 if (GET_CODE (addr) == PRE_MODIFY
13829 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13835 if (VECTOR_UNIT_ALTIVEC_P (mode))
13836 return ALTIVEC_REGS;
13844 /* Debug version of rs6000_preferred_reload_class. */
13845 static enum reg_class
13846 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13848 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13851 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13853 reg_class_names[ret], reg_class_names[rclass],
13854 GET_MODE_NAME (GET_MODE (x)));
13860 /* If we are copying between FP or AltiVec registers and anything else, we need
13861 a memory location. The exception is when we are targeting ppc64 and the
13862 move to/from fpr to gpr instructions are available. Also, under VSX, you
13863 can copy vector registers from the FP register set to the Altivec register
13864 set and vice versa. */
13867 rs6000_secondary_memory_needed (enum reg_class class1,
13868 enum reg_class class2,
13869 enum machine_mode mode)
13871 if (class1 == class2)
13874 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13875 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13876 between these classes. But we need memory for other things that can go in
13877 FLOAT_REGS like SFmode. */
13879 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13880 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13881 || class1 == FLOAT_REGS))
13882 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13883 && class2 != FLOAT_REGS);
13885 if (class1 == VSX_REGS || class2 == VSX_REGS)
13888 if (class1 == FLOAT_REGS
13889 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13890 || ((mode != DFmode)
13891 && (mode != DDmode)
13892 && (mode != DImode))))
13895 if (class2 == FLOAT_REGS
13896 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13897 || ((mode != DFmode)
13898 && (mode != DDmode)
13899 && (mode != DImode))))
13902 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13908 /* Debug version of rs6000_secondary_memory_needed. */
13910 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13911 enum reg_class class2,
13912 enum machine_mode mode)
13914 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13917 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13918 "class2 = %s, mode = %s\n",
13919 ret ? "true" : "false", reg_class_names[class1],
13920 reg_class_names[class2], GET_MODE_NAME (mode));
13925 /* Return the register class of a scratch register needed to copy IN into
13926 or out of a register in RCLASS in MODE. If it can be done directly,
13927 NO_REGS is returned. */
13929 static enum reg_class
13930 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13935 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13937 && MACHOPIC_INDIRECT
13941 /* We cannot copy a symbolic operand directly into anything
13942 other than BASE_REGS for TARGET_ELF. So indicate that a
13943 register from BASE_REGS is needed as an intermediate
13946 On Darwin, pic addresses require a load from memory, which
13947 needs a base register. */
13948 if (rclass != BASE_REGS
13949 && (GET_CODE (in) == SYMBOL_REF
13950 || GET_CODE (in) == HIGH
13951 || GET_CODE (in) == LABEL_REF
13952 || GET_CODE (in) == CONST))
13956 if (GET_CODE (in) == REG)
13958 regno = REGNO (in);
13959 if (regno >= FIRST_PSEUDO_REGISTER)
13961 regno = true_regnum (in);
13962 if (regno >= FIRST_PSEUDO_REGISTER)
13966 else if (GET_CODE (in) == SUBREG)
13968 regno = true_regnum (in);
13969 if (regno >= FIRST_PSEUDO_REGISTER)
13975 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13977 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13978 || (regno >= 0 && INT_REGNO_P (regno)))
13981 /* Constants, memory, and FP registers can go into FP registers. */
13982 if ((regno == -1 || FP_REGNO_P (regno))
13983 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13984 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13986 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13989 && (regno == -1 || VSX_REGNO_P (regno))
13990 && VSX_REG_CLASS_P (rclass))
13993 /* Memory, and AltiVec registers can go into AltiVec registers. */
13994 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13995 && rclass == ALTIVEC_REGS)
13998 /* We can copy among the CR registers. */
13999 if ((rclass == CR_REGS || rclass == CR0_REGS)
14000 && regno >= 0 && CR_REGNO_P (regno))
14003 /* Otherwise, we need GENERAL_REGS. */
14004 return GENERAL_REGS;
14007 /* Debug version of rs6000_secondary_reload_class. */
14008 static enum reg_class
14009 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14010 enum machine_mode mode, rtx in)
14012 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14014 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14015 "mode = %s, input rtx:\n",
14016 reg_class_names[ret], reg_class_names[rclass],
14017 GET_MODE_NAME (mode));
14023 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14026 rs6000_cannot_change_mode_class (enum machine_mode from,
14027 enum machine_mode to,
14028 enum reg_class rclass)
14030 unsigned from_size = GET_MODE_SIZE (from);
14031 unsigned to_size = GET_MODE_SIZE (to);
14033 if (from_size != to_size)
14035 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14036 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14037 && reg_classes_intersect_p (xclass, rclass));
14040 if (TARGET_E500_DOUBLE
14041 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14042 || (((to) == TFmode) + ((from) == TFmode)) == 1
14043 || (((to) == DDmode) + ((from) == DDmode)) == 1
14044 || (((to) == TDmode) + ((from) == TDmode)) == 1
14045 || (((to) == DImode) + ((from) == DImode)) == 1))
14048 /* Since the VSX register set includes traditional floating point registers
14049 and altivec registers, just check for the size being different instead of
14050 trying to check whether the modes are vector modes. Otherwise it won't
14051 allow say DF and DI to change classes. */
14052 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14053 return (from_size != 8 && from_size != 16);
14055 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14056 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14059 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14060 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14066 /* Debug version of rs6000_cannot_change_mode_class. */
14068 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14069 enum machine_mode to,
14070 enum reg_class rclass)
14072 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14075 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14076 "to = %s, rclass = %s\n",
14077 ret ? "true" : "false",
14078 GET_MODE_NAME (from), GET_MODE_NAME (to),
14079 reg_class_names[rclass]);
14084 /* Given a comparison operation, return the bit number in CCR to test. We
14085 know this is a valid comparison.
14087 SCC_P is 1 if this is for an scc. That means that %D will have been
14088 used instead of %C, so the bits will be in different places.
14090 Return -1 if OP isn't a valid comparison for some reason. */
14093 ccr_bit (rtx op, int scc_p)
14095 enum rtx_code code = GET_CODE (op);
14096 enum machine_mode cc_mode;
14101 if (!COMPARISON_P (op))
14104 reg = XEXP (op, 0);
14106 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14108 cc_mode = GET_MODE (reg);
14109 cc_regnum = REGNO (reg);
14110 base_bit = 4 * (cc_regnum - CR0_REGNO);
14112 validate_condition_mode (code, cc_mode);
14114 /* When generating a sCOND operation, only positive conditions are
14117 || code == EQ || code == GT || code == LT || code == UNORDERED
14118 || code == GTU || code == LTU);
14123 return scc_p ? base_bit + 3 : base_bit + 2;
14125 return base_bit + 2;
14126 case GT: case GTU: case UNLE:
14127 return base_bit + 1;
14128 case LT: case LTU: case UNGE:
14130 case ORDERED: case UNORDERED:
14131 return base_bit + 3;
14134 /* If scc, we will have done a cror to put the bit in the
14135 unordered position. So test that bit. For integer, this is ! LT
14136 unless this is an scc insn. */
14137 return scc_p ? base_bit + 3 : base_bit;
14140 return scc_p ? base_bit + 3 : base_bit + 1;
14143 gcc_unreachable ();
14147 /* Return the GOT register. */
14150 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14152 /* The second flow pass currently (June 1999) can't update
14153 regs_ever_live without disturbing other parts of the compiler, so
14154 update it here to make the prolog/epilogue code happy. */
14155 if (!can_create_pseudo_p ()
14156 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14157 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14159 crtl->uses_pic_offset_table = 1;
14161 return pic_offset_table_rtx;
14164 /* Function to init struct machine_function.
14165 This will be called, via a pointer variable,
14166 from push_function_context. */
14168 static struct machine_function *
14169 rs6000_init_machine_status (void)
14171 return GGC_CNEW (machine_function);
14174 /* These macros test for integers and extract the low-order bits. */
14176 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14177 && GET_MODE (X) == VOIDmode)
14179 #define INT_LOWPART(X) \
14180 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14183 extract_MB (rtx op)
14186 unsigned long val = INT_LOWPART (op);
14188 /* If the high bit is zero, the value is the first 1 bit we find
14190 if ((val & 0x80000000) == 0)
14192 gcc_assert (val & 0xffffffff);
14195 while (((val <<= 1) & 0x80000000) == 0)
14200 /* If the high bit is set and the low bit is not, or the mask is all
14201 1's, the value is zero. */
14202 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14205 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14208 while (((val >>= 1) & 1) != 0)
14215 extract_ME (rtx op)
14218 unsigned long val = INT_LOWPART (op);
14220 /* If the low bit is zero, the value is the first 1 bit we find from
14222 if ((val & 1) == 0)
14224 gcc_assert (val & 0xffffffff);
14227 while (((val >>= 1) & 1) == 0)
14233 /* If the low bit is set and the high bit is not, or the mask is all
14234 1's, the value is 31. */
14235 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14238 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14241 while (((val <<= 1) & 0x80000000) != 0)
14247 /* Locate some local-dynamic symbol still in use by this function
14248 so that we can print its name in some tls_ld pattern. */
14250 static const char *
14251 rs6000_get_some_local_dynamic_name (void)
14255 if (cfun->machine->some_ld_name)
14256 return cfun->machine->some_ld_name;
14258 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14260 && for_each_rtx (&PATTERN (insn),
14261 rs6000_get_some_local_dynamic_name_1, 0))
14262 return cfun->machine->some_ld_name;
14264 gcc_unreachable ();
14267 /* Helper function for rs6000_get_some_local_dynamic_name. */
14270 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14274 if (GET_CODE (x) == SYMBOL_REF)
14276 const char *str = XSTR (x, 0);
14277 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14279 cfun->machine->some_ld_name = str;
14287 /* Write out a function code label. */
14290 rs6000_output_function_entry (FILE *file, const char *fname)
14292 if (fname[0] != '.')
14294 switch (DEFAULT_ABI)
14297 gcc_unreachable ();
14303 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14312 RS6000_OUTPUT_BASENAME (file, fname);
14314 assemble_name (file, fname);
14317 /* Print an operand. Recognize special options, documented below. */
14320 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14321 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14323 #define SMALL_DATA_RELOC "sda21"
14324 #define SMALL_DATA_REG 0
14328 print_operand (FILE *file, rtx x, int code)
14332 unsigned HOST_WIDE_INT uval;
14337 /* Write out an instruction after the call which may be replaced
14338 with glue code by the loader. This depends on the AIX version. */
14339 asm_fprintf (file, RS6000_CALL_GLUE);
14342 /* %a is output_address. */
14345 /* If X is a constant integer whose low-order 5 bits are zero,
14346 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14347 in the AIX assembler where "sri" with a zero shift count
14348 writes a trash instruction. */
14349 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14356 /* If constant, low-order 16 bits of constant, unsigned.
14357 Otherwise, write normally. */
14359 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14361 print_operand (file, x, 0);
14365 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14366 for 64-bit mask direction. */
14367 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14370 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14374 /* X is a CR register. Print the number of the GT bit of the CR. */
14375 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14376 output_operand_lossage ("invalid %%c value");
14378 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14382 /* Like 'J' but get to the GT bit only. */
14383 gcc_assert (GET_CODE (x) == REG);
14385 /* Bit 1 is GT bit. */
14386 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14388 /* Add one for shift count in rlinm for scc. */
14389 fprintf (file, "%d", i + 1);
14393 /* X is a CR register. Print the number of the EQ bit of the CR */
14394 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14395 output_operand_lossage ("invalid %%E value");
14397 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14401 /* X is a CR register. Print the shift count needed to move it
14402 to the high-order four bits. */
14403 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14404 output_operand_lossage ("invalid %%f value");
14406 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14410 /* Similar, but print the count for the rotate in the opposite
14412 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14413 output_operand_lossage ("invalid %%F value");
14415 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14419 /* X is a constant integer. If it is negative, print "m",
14420 otherwise print "z". This is to make an aze or ame insn. */
14421 if (GET_CODE (x) != CONST_INT)
14422 output_operand_lossage ("invalid %%G value");
14423 else if (INTVAL (x) >= 0)
14430 /* If constant, output low-order five bits. Otherwise, write
14433 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14435 print_operand (file, x, 0);
14439 /* If constant, output low-order six bits. Otherwise, write
14442 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14444 print_operand (file, x, 0);
14448 /* Print `i' if this is a constant, else nothing. */
14454 /* Write the bit number in CCR for jump. */
14455 i = ccr_bit (x, 0);
14457 output_operand_lossage ("invalid %%j code");
14459 fprintf (file, "%d", i);
14463 /* Similar, but add one for shift count in rlinm for scc and pass
14464 scc flag to `ccr_bit'. */
14465 i = ccr_bit (x, 1);
14467 output_operand_lossage ("invalid %%J code");
14469 /* If we want bit 31, write a shift count of zero, not 32. */
14470 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14474 /* X must be a constant. Write the 1's complement of the
14477 output_operand_lossage ("invalid %%k value");
14479 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14483 /* X must be a symbolic constant on ELF. Write an
14484 expression suitable for an 'addi' that adds in the low 16
14485 bits of the MEM. */
14486 if (GET_CODE (x) != CONST)
14488 print_operand_address (file, x);
14489 fputs ("@l", file);
14493 if (GET_CODE (XEXP (x, 0)) != PLUS
14494 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14495 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14496 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14497 output_operand_lossage ("invalid %%K value");
14498 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14499 fputs ("@l", file);
14500 /* For GNU as, there must be a non-alphanumeric character
14501 between 'l' and the number. The '-' is added by
14502 print_operand() already. */
14503 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14505 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14509 /* %l is output_asm_label. */
14512 /* Write second word of DImode or DFmode reference. Works on register
14513 or non-indexed memory only. */
14514 if (GET_CODE (x) == REG)
14515 fputs (reg_names[REGNO (x) + 1], file);
14516 else if (GET_CODE (x) == MEM)
14518 /* Handle possible auto-increment. Since it is pre-increment and
14519 we have already done it, we can just use an offset of word. */
14520 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14521 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14522 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14524 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14525 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14528 output_address (XEXP (adjust_address_nv (x, SImode,
14532 if (small_data_operand (x, GET_MODE (x)))
14533 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14534 reg_names[SMALL_DATA_REG]);
14539 /* MB value for a mask operand. */
14540 if (! mask_operand (x, SImode))
14541 output_operand_lossage ("invalid %%m value");
14543 fprintf (file, "%d", extract_MB (x));
14547 /* ME value for a mask operand. */
14548 if (! mask_operand (x, SImode))
14549 output_operand_lossage ("invalid %%M value");
14551 fprintf (file, "%d", extract_ME (x));
14554 /* %n outputs the negative of its operand. */
14557 /* Write the number of elements in the vector times 4. */
14558 if (GET_CODE (x) != PARALLEL)
14559 output_operand_lossage ("invalid %%N value");
14561 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14565 /* Similar, but subtract 1 first. */
14566 if (GET_CODE (x) != PARALLEL)
14567 output_operand_lossage ("invalid %%O value");
14569 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14573 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14575 || INT_LOWPART (x) < 0
14576 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14577 output_operand_lossage ("invalid %%p value");
14579 fprintf (file, "%d", i);
14583 /* The operand must be an indirect memory reference. The result
14584 is the register name. */
14585 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14586 || REGNO (XEXP (x, 0)) >= 32)
14587 output_operand_lossage ("invalid %%P value");
14589 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14593 /* This outputs the logical code corresponding to a boolean
14594 expression. The expression may have one or both operands
14595 negated (if one, only the first one). For condition register
14596 logical operations, it will also treat the negated
14597 CR codes as NOTs, but not handle NOTs of them. */
14599 const char *const *t = 0;
14601 enum rtx_code code = GET_CODE (x);
14602 static const char * const tbl[3][3] = {
14603 { "and", "andc", "nor" },
14604 { "or", "orc", "nand" },
14605 { "xor", "eqv", "xor" } };
14609 else if (code == IOR)
14611 else if (code == XOR)
14614 output_operand_lossage ("invalid %%q value");
14616 if (GET_CODE (XEXP (x, 0)) != NOT)
14620 if (GET_CODE (XEXP (x, 1)) == NOT)
14638 /* X is a CR register. Print the mask for `mtcrf'. */
14639 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14640 output_operand_lossage ("invalid %%R value");
14642 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14646 /* Low 5 bits of 32 - value */
14648 output_operand_lossage ("invalid %%s value");
14650 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14654 /* PowerPC64 mask position. All 0's is excluded.
14655 CONST_INT 32-bit mask is considered sign-extended so any
14656 transition must occur within the CONST_INT, not on the boundary. */
14657 if (! mask64_operand (x, DImode))
14658 output_operand_lossage ("invalid %%S value");
14660 uval = INT_LOWPART (x);
14662 if (uval & 1) /* Clear Left */
14664 #if HOST_BITS_PER_WIDE_INT > 64
14665 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14669 else /* Clear Right */
14672 #if HOST_BITS_PER_WIDE_INT > 64
14673 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14679 gcc_assert (i >= 0);
14680 fprintf (file, "%d", i);
14684 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14685 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14687 /* Bit 3 is OV bit. */
14688 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14690 /* If we want bit 31, write a shift count of zero, not 32. */
14691 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14695 /* Print the symbolic name of a branch target register. */
14696 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14697 && REGNO (x) != CTR_REGNO))
14698 output_operand_lossage ("invalid %%T value");
14699 else if (REGNO (x) == LR_REGNO)
14700 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14702 fputs ("ctr", file);
14706 /* High-order 16 bits of constant for use in unsigned operand. */
14708 output_operand_lossage ("invalid %%u value");
14710 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14711 (INT_LOWPART (x) >> 16) & 0xffff);
14715 /* High-order 16 bits of constant for use in signed operand. */
14717 output_operand_lossage ("invalid %%v value");
14719 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14720 (INT_LOWPART (x) >> 16) & 0xffff);
14724 /* Print `u' if this has an auto-increment or auto-decrement. */
14725 if (GET_CODE (x) == MEM
14726 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14727 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14728 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14733 /* Print the trap code for this operand. */
14734 switch (GET_CODE (x))
14737 fputs ("eq", file); /* 4 */
14740 fputs ("ne", file); /* 24 */
14743 fputs ("lt", file); /* 16 */
14746 fputs ("le", file); /* 20 */
14749 fputs ("gt", file); /* 8 */
14752 fputs ("ge", file); /* 12 */
14755 fputs ("llt", file); /* 2 */
14758 fputs ("lle", file); /* 6 */
14761 fputs ("lgt", file); /* 1 */
14764 fputs ("lge", file); /* 5 */
14767 gcc_unreachable ();
14772 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14775 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14776 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14778 print_operand (file, x, 0);
14782 /* MB value for a PowerPC64 rldic operand. */
14783 val = (GET_CODE (x) == CONST_INT
14784 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14789 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14790 if ((val <<= 1) < 0)
14793 #if HOST_BITS_PER_WIDE_INT == 32
14794 if (GET_CODE (x) == CONST_INT && i >= 0)
14795 i += 32; /* zero-extend high-part was all 0's */
14796 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14798 val = CONST_DOUBLE_LOW (x);
14804 for ( ; i < 64; i++)
14805 if ((val <<= 1) < 0)
14810 fprintf (file, "%d", i + 1);
14814 /* X is a FPR or Altivec register used in a VSX context. */
14815 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14816 output_operand_lossage ("invalid %%x value");
14819 int reg = REGNO (x);
14820 int vsx_reg = (FP_REGNO_P (reg)
14822 : reg - FIRST_ALTIVEC_REGNO + 32);
14824 #ifdef TARGET_REGNAMES
14825 if (TARGET_REGNAMES)
14826 fprintf (file, "%%vs%d", vsx_reg);
14829 fprintf (file, "%d", vsx_reg);
14834 if (GET_CODE (x) == MEM
14835 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14836 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14837 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14842 /* Like 'L', for third word of TImode */
14843 if (GET_CODE (x) == REG)
14844 fputs (reg_names[REGNO (x) + 2], file);
14845 else if (GET_CODE (x) == MEM)
14847 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14848 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14849 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14850 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14851 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14853 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14854 if (small_data_operand (x, GET_MODE (x)))
14855 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14856 reg_names[SMALL_DATA_REG]);
14861 /* X is a SYMBOL_REF. Write out the name preceded by a
14862 period and without any trailing data in brackets. Used for function
14863 names. If we are configured for System V (or the embedded ABI) on
14864 the PowerPC, do not emit the period, since those systems do not use
14865 TOCs and the like. */
14866 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14868 /* Mark the decl as referenced so that cgraph will output the
14870 if (SYMBOL_REF_DECL (x))
14871 mark_decl_referenced (SYMBOL_REF_DECL (x));
14873 /* For macho, check to see if we need a stub. */
14876 const char *name = XSTR (x, 0);
14878 if (MACHOPIC_INDIRECT
14879 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14880 name = machopic_indirection_name (x, /*stub_p=*/true);
14882 assemble_name (file, name);
14884 else if (!DOT_SYMBOLS)
14885 assemble_name (file, XSTR (x, 0));
14887 rs6000_output_function_entry (file, XSTR (x, 0));
14891 /* Like 'L', for last word of TImode. */
14892 if (GET_CODE (x) == REG)
14893 fputs (reg_names[REGNO (x) + 3], file);
14894 else if (GET_CODE (x) == MEM)
14896 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14897 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14898 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14899 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14900 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14902 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14903 if (small_data_operand (x, GET_MODE (x)))
14904 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14905 reg_names[SMALL_DATA_REG]);
14909 /* Print AltiVec or SPE memory operand. */
14914 gcc_assert (GET_CODE (x) == MEM);
14918 /* Ugly hack because %y is overloaded. */
14919 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14920 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14921 || GET_MODE (x) == TFmode
14922 || GET_MODE (x) == TImode))
14924 /* Handle [reg]. */
14925 if (GET_CODE (tmp) == REG)
14927 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14930 /* Handle [reg+UIMM]. */
14931 else if (GET_CODE (tmp) == PLUS &&
14932 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14936 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14938 x = INTVAL (XEXP (tmp, 1));
14939 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14943 /* Fall through. Must be [reg+reg]. */
14945 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14946 && GET_CODE (tmp) == AND
14947 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14948 && INTVAL (XEXP (tmp, 1)) == -16)
14949 tmp = XEXP (tmp, 0);
14950 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14951 && GET_CODE (tmp) == PRE_MODIFY)
14952 tmp = XEXP (tmp, 1);
14953 if (GET_CODE (tmp) == REG)
14954 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14957 if (!GET_CODE (tmp) == PLUS
14958 || !REG_P (XEXP (tmp, 0))
14959 || !REG_P (XEXP (tmp, 1)))
14961 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14965 if (REGNO (XEXP (tmp, 0)) == 0)
14966 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14967 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14969 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14970 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14976 if (GET_CODE (x) == REG)
14977 fprintf (file, "%s", reg_names[REGNO (x)]);
14978 else if (GET_CODE (x) == MEM)
14980 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14981 know the width from the mode. */
14982 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14983 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14984 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14985 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14986 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14987 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14988 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14989 output_address (XEXP (XEXP (x, 0), 1));
14991 output_address (XEXP (x, 0));
14994 output_addr_const (file, x);
14998 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15002 output_operand_lossage ("invalid %%xn code");
15006 /* Print the address of an operand. */
15009 print_operand_address (FILE *file, rtx x)
15011 if (GET_CODE (x) == REG)
15012 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15013 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15014 || GET_CODE (x) == LABEL_REF)
15016 output_addr_const (file, x);
15017 if (small_data_operand (x, GET_MODE (x)))
15018 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15019 reg_names[SMALL_DATA_REG]);
15021 gcc_assert (!TARGET_TOC);
15023 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15025 gcc_assert (REG_P (XEXP (x, 0)));
15026 if (REGNO (XEXP (x, 0)) == 0)
15027 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15028 reg_names[ REGNO (XEXP (x, 0)) ]);
15030 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15031 reg_names[ REGNO (XEXP (x, 1)) ]);
15033 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15034 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15035 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15037 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15038 && CONSTANT_P (XEXP (x, 1)))
15040 output_addr_const (file, XEXP (x, 1));
15041 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15045 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15046 && CONSTANT_P (XEXP (x, 1)))
15048 fprintf (file, "lo16(");
15049 output_addr_const (file, XEXP (x, 1));
15050 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15053 else if (legitimate_constant_pool_address_p (x))
15055 output_addr_const (file, XEXP (x, 1));
15056 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15059 gcc_unreachable ();
15062 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15065 rs6000_output_addr_const_extra (FILE *file, rtx x)
15067 if (GET_CODE (x) == UNSPEC)
15068 switch (XINT (x, 1))
15070 case UNSPEC_TOCREL:
15071 x = XVECEXP (x, 0, 0);
15072 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15073 output_addr_const (file, x);
15074 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15077 assemble_name (file, toc_label_name);
15079 else if (TARGET_ELF)
15080 fputs ("@toc", file);
15084 case UNSPEC_MACHOPIC_OFFSET:
15085 output_addr_const (file, XVECEXP (x, 0, 0));
15087 machopic_output_function_base_name (file);
15094 /* Target hook for assembling integer objects. The PowerPC version has
15095 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15096 is defined. It also needs to handle DI-mode objects on 64-bit
15100 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15102 #ifdef RELOCATABLE_NEEDS_FIXUP
15103 /* Special handling for SI values. */
15104 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15106 static int recurse = 0;
15108 /* For -mrelocatable, we mark all addresses that need to be fixed up
15109 in the .fixup section. */
15110 if (TARGET_RELOCATABLE
15111 && in_section != toc_section
15112 && in_section != text_section
15113 && !unlikely_text_section_p (in_section)
15115 && GET_CODE (x) != CONST_INT
15116 && GET_CODE (x) != CONST_DOUBLE
15122 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15124 ASM_OUTPUT_LABEL (asm_out_file, buf);
15125 fprintf (asm_out_file, "\t.long\t(");
15126 output_addr_const (asm_out_file, x);
15127 fprintf (asm_out_file, ")@fixup\n");
15128 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15129 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15130 fprintf (asm_out_file, "\t.long\t");
15131 assemble_name (asm_out_file, buf);
15132 fprintf (asm_out_file, "\n\t.previous\n");
15136 /* Remove initial .'s to turn a -mcall-aixdesc function
15137 address into the address of the descriptor, not the function
15139 else if (GET_CODE (x) == SYMBOL_REF
15140 && XSTR (x, 0)[0] == '.'
15141 && DEFAULT_ABI == ABI_AIX)
15143 const char *name = XSTR (x, 0);
15144 while (*name == '.')
15147 fprintf (asm_out_file, "\t.long\t%s\n", name);
15151 #endif /* RELOCATABLE_NEEDS_FIXUP */
15152 return default_assemble_integer (x, size, aligned_p);
15155 #ifdef HAVE_GAS_HIDDEN
15156 /* Emit an assembler directive to set symbol visibility for DECL to
15157 VISIBILITY_TYPE. */
15160 rs6000_assemble_visibility (tree decl, int vis)
15162 /* Functions need to have their entry point symbol visibility set as
15163 well as their descriptor symbol visibility. */
15164 if (DEFAULT_ABI == ABI_AIX
15166 && TREE_CODE (decl) == FUNCTION_DECL)
15168 static const char * const visibility_types[] = {
15169 NULL, "internal", "hidden", "protected"
15172 const char *name, *type;
15174 name = ((* targetm.strip_name_encoding)
15175 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15176 type = visibility_types[vis];
15178 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15179 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15182 default_assemble_visibility (decl, vis);
15187 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15189 /* Reversal of FP compares takes care -- an ordered compare
15190 becomes an unordered compare and vice versa. */
15191 if (mode == CCFPmode
15192 && (!flag_finite_math_only
15193 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15194 || code == UNEQ || code == LTGT))
15195 return reverse_condition_maybe_unordered (code);
15197 return reverse_condition (code);
15200 /* Generate a compare for CODE. Return a brand-new rtx that
15201 represents the result of the compare. */
15204 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15206 enum machine_mode comp_mode;
15207 rtx compare_result;
15208 enum rtx_code code = GET_CODE (cmp);
15209 rtx op0 = XEXP (cmp, 0);
15210 rtx op1 = XEXP (cmp, 1);
15212 if (FLOAT_MODE_P (mode))
15213 comp_mode = CCFPmode;
15214 else if (code == GTU || code == LTU
15215 || code == GEU || code == LEU)
15216 comp_mode = CCUNSmode;
15217 else if ((code == EQ || code == NE)
15218 && GET_CODE (op0) == SUBREG
15219 && GET_CODE (op1) == SUBREG
15220 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15221 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15222 /* These are unsigned values, perhaps there will be a later
15223 ordering compare that can be shared with this one.
15224 Unfortunately we cannot detect the signedness of the operands
15225 for non-subregs. */
15226 comp_mode = CCUNSmode;
15228 comp_mode = CCmode;
15230 /* First, the compare. */
15231 compare_result = gen_reg_rtx (comp_mode);
15233 /* E500 FP compare instructions on the GPRs. Yuck! */
15234 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15235 && FLOAT_MODE_P (mode))
15237 rtx cmp, or_result, compare_result2;
15238 enum machine_mode op_mode = GET_MODE (op0);
15240 if (op_mode == VOIDmode)
15241 op_mode = GET_MODE (op1);
15243 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15244 This explains the following mess. */
15248 case EQ: case UNEQ: case NE: case LTGT:
15252 cmp = (flag_finite_math_only && !flag_trapping_math)
15253 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15254 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15258 cmp = (flag_finite_math_only && !flag_trapping_math)
15259 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15260 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15264 cmp = (flag_finite_math_only && !flag_trapping_math)
15265 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15266 : gen_cmptfeq_gpr (compare_result, op0, op1);
15270 gcc_unreachable ();
15274 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15278 cmp = (flag_finite_math_only && !flag_trapping_math)
15279 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15280 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15284 cmp = (flag_finite_math_only && !flag_trapping_math)
15285 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15286 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15290 cmp = (flag_finite_math_only && !flag_trapping_math)
15291 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15292 : gen_cmptfgt_gpr (compare_result, op0, op1);
15296 gcc_unreachable ();
15300 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15304 cmp = (flag_finite_math_only && !flag_trapping_math)
15305 ? gen_tstsflt_gpr (compare_result, op0, op1)
15306 : gen_cmpsflt_gpr (compare_result, op0, op1);
15310 cmp = (flag_finite_math_only && !flag_trapping_math)
15311 ? gen_tstdflt_gpr (compare_result, op0, op1)
15312 : gen_cmpdflt_gpr (compare_result, op0, op1);
15316 cmp = (flag_finite_math_only && !flag_trapping_math)
15317 ? gen_tsttflt_gpr (compare_result, op0, op1)
15318 : gen_cmptflt_gpr (compare_result, op0, op1);
15322 gcc_unreachable ();
15326 gcc_unreachable ();
15329 /* Synthesize LE and GE from LT/GT || EQ. */
15330 if (code == LE || code == GE || code == LEU || code == GEU)
15336 case LE: code = LT; break;
15337 case GE: code = GT; break;
15338 case LEU: code = LT; break;
15339 case GEU: code = GT; break;
15340 default: gcc_unreachable ();
15343 compare_result2 = gen_reg_rtx (CCFPmode);
15349 cmp = (flag_finite_math_only && !flag_trapping_math)
15350 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15351 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15355 cmp = (flag_finite_math_only && !flag_trapping_math)
15356 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15357 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15361 cmp = (flag_finite_math_only && !flag_trapping_math)
15362 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15363 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15367 gcc_unreachable ();
15371 /* OR them together. */
15372 or_result = gen_reg_rtx (CCFPmode);
15373 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15375 compare_result = or_result;
15380 if (code == NE || code == LTGT)
15390 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15391 CLOBBERs to match cmptf_internal2 pattern. */
15392 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15393 && GET_MODE (op0) == TFmode
15394 && !TARGET_IEEEQUAD
15395 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15396 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15398 gen_rtx_SET (VOIDmode,
15400 gen_rtx_COMPARE (comp_mode, op0, op1)),
15401 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15402 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15403 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15404 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15405 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15406 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15407 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15408 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15409 else if (GET_CODE (op1) == UNSPEC
15410 && XINT (op1, 1) == UNSPEC_SP_TEST)
15412 rtx op1b = XVECEXP (op1, 0, 0);
15413 comp_mode = CCEQmode;
15414 compare_result = gen_reg_rtx (CCEQmode);
15416 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15418 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15421 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15422 gen_rtx_COMPARE (comp_mode, op0, op1)));
15425 /* Some kinds of FP comparisons need an OR operation;
15426 under flag_finite_math_only we don't bother. */
15427 if (FLOAT_MODE_P (mode)
15428 && !flag_finite_math_only
15429 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15430 && (code == LE || code == GE
15431 || code == UNEQ || code == LTGT
15432 || code == UNGT || code == UNLT))
15434 enum rtx_code or1, or2;
15435 rtx or1_rtx, or2_rtx, compare2_rtx;
15436 rtx or_result = gen_reg_rtx (CCEQmode);
15440 case LE: or1 = LT; or2 = EQ; break;
15441 case GE: or1 = GT; or2 = EQ; break;
15442 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15443 case LTGT: or1 = LT; or2 = GT; break;
15444 case UNGT: or1 = UNORDERED; or2 = GT; break;
15445 case UNLT: or1 = UNORDERED; or2 = LT; break;
15446 default: gcc_unreachable ();
15448 validate_condition_mode (or1, comp_mode);
15449 validate_condition_mode (or2, comp_mode);
15450 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15451 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15452 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15453 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15455 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15457 compare_result = or_result;
15461 validate_condition_mode (code, GET_MODE (compare_result));
15463 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15467 /* Emit the RTL for an sCOND pattern. */
15470 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15473 enum machine_mode op_mode;
15474 enum rtx_code cond_code;
15475 rtx result = operands[0];
15477 condition_rtx = rs6000_generate_compare (operands[1], mode);
15478 cond_code = GET_CODE (condition_rtx);
15480 op_mode = GET_MODE (XEXP (operands[1], 0));
15481 if (op_mode == VOIDmode)
15482 op_mode = GET_MODE (XEXP (operands[1], 1));
15484 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15486 PUT_MODE (condition_rtx, DImode);
15487 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15488 || cond_code == LTU)
15489 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15490 force_reg (DImode, const1_rtx),
15491 force_reg (DImode, const0_rtx),
15492 XEXP (condition_rtx, 0)));
15494 emit_insn (gen_isel_signed_di (result, condition_rtx,
15495 force_reg (DImode, const1_rtx),
15496 force_reg (DImode, const0_rtx),
15497 XEXP (condition_rtx, 0)));
15501 PUT_MODE (condition_rtx, SImode);
15502 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15503 || cond_code == LTU)
15504 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15505 force_reg (SImode, const1_rtx),
15506 force_reg (SImode, const0_rtx),
15507 XEXP (condition_rtx, 0)));
15509 emit_insn (gen_isel_signed_si (result, condition_rtx,
15510 force_reg (SImode, const1_rtx),
15511 force_reg (SImode, const0_rtx),
15512 XEXP (condition_rtx, 0)));
15517 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15520 enum machine_mode op_mode;
15521 enum rtx_code cond_code;
15522 rtx result = operands[0];
15524 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15526 rs6000_emit_sISEL (mode, operands);
15530 condition_rtx = rs6000_generate_compare (operands[1], mode);
15531 cond_code = GET_CODE (condition_rtx);
15533 if (FLOAT_MODE_P (mode)
15534 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15538 PUT_MODE (condition_rtx, SImode);
15539 t = XEXP (condition_rtx, 0);
15541 gcc_assert (cond_code == NE || cond_code == EQ);
15543 if (cond_code == NE)
15544 emit_insn (gen_e500_flip_gt_bit (t, t));
15546 emit_insn (gen_move_from_CR_gt_bit (result, t));
15550 if (cond_code == NE
15551 || cond_code == GE || cond_code == LE
15552 || cond_code == GEU || cond_code == LEU
15553 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15555 rtx not_result = gen_reg_rtx (CCEQmode);
15556 rtx not_op, rev_cond_rtx;
15557 enum machine_mode cc_mode;
15559 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15561 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15562 SImode, XEXP (condition_rtx, 0), const0_rtx);
15563 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15564 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15565 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15568 op_mode = GET_MODE (XEXP (operands[1], 0));
15569 if (op_mode == VOIDmode)
15570 op_mode = GET_MODE (XEXP (operands[1], 1));
15572 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15574 PUT_MODE (condition_rtx, DImode);
15575 convert_move (result, condition_rtx, 0);
15579 PUT_MODE (condition_rtx, SImode);
15580 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15584 /* Emit a branch of kind CODE to location LOC. */
15587 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15589 rtx condition_rtx, loc_ref;
15591 condition_rtx = rs6000_generate_compare (operands[0], mode);
15592 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15593 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15594 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15595 loc_ref, pc_rtx)));
15598 /* Return the string to output a conditional branch to LABEL, which is
15599 the operand number of the label, or -1 if the branch is really a
15600 conditional return.
15602 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15603 condition code register and its mode specifies what kind of
15604 comparison we made.
15606 REVERSED is nonzero if we should reverse the sense of the comparison.
15608 INSN is the insn. */
15611 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15613 static char string[64];
15614 enum rtx_code code = GET_CODE (op);
15615 rtx cc_reg = XEXP (op, 0);
15616 enum machine_mode mode = GET_MODE (cc_reg);
15617 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15618 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15619 int really_reversed = reversed ^ need_longbranch;
15625 validate_condition_mode (code, mode);
15627 /* Work out which way this really branches. We could use
15628 reverse_condition_maybe_unordered here always but this
15629 makes the resulting assembler clearer. */
15630 if (really_reversed)
15632 /* Reversal of FP compares takes care -- an ordered compare
15633 becomes an unordered compare and vice versa. */
15634 if (mode == CCFPmode)
15635 code = reverse_condition_maybe_unordered (code);
15637 code = reverse_condition (code);
15640 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15642 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15647 /* Opposite of GT. */
15656 gcc_unreachable ();
15662 /* Not all of these are actually distinct opcodes, but
15663 we distinguish them for clarity of the resulting assembler. */
15664 case NE: case LTGT:
15665 ccode = "ne"; break;
15666 case EQ: case UNEQ:
15667 ccode = "eq"; break;
15669 ccode = "ge"; break;
15670 case GT: case GTU: case UNGT:
15671 ccode = "gt"; break;
15673 ccode = "le"; break;
15674 case LT: case LTU: case UNLT:
15675 ccode = "lt"; break;
15676 case UNORDERED: ccode = "un"; break;
15677 case ORDERED: ccode = "nu"; break;
15678 case UNGE: ccode = "nl"; break;
15679 case UNLE: ccode = "ng"; break;
15681 gcc_unreachable ();
15684 /* Maybe we have a guess as to how likely the branch is.
15685 The old mnemonics don't have a way to specify this information. */
15687 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15688 if (note != NULL_RTX)
15690 /* PROB is the difference from 50%. */
15691 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15693 /* Only hint for highly probable/improbable branches on newer
15694 cpus as static prediction overrides processor dynamic
15695 prediction. For older cpus we may as well always hint, but
15696 assume not taken for branches that are very close to 50% as a
15697 mispredicted taken branch is more expensive than a
15698 mispredicted not-taken branch. */
15699 if (rs6000_always_hint
15700 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15701 && br_prob_note_reliable_p (note)))
15703 if (abs (prob) > REG_BR_PROB_BASE / 20
15704 && ((prob > 0) ^ need_longbranch))
15712 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15714 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15716 /* We need to escape any '%' characters in the reg_names string.
15717 Assume they'd only be the first character.... */
15718 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15720 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15724 /* If the branch distance was too far, we may have to use an
15725 unconditional branch to go the distance. */
15726 if (need_longbranch)
15727 s += sprintf (s, ",$+8\n\tb %s", label);
15729 s += sprintf (s, ",%s", label);
15735 /* Return the string to flip the GT bit on a CR. */
15737 output_e500_flip_gt_bit (rtx dst, rtx src)
15739 static char string[64];
15742 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15743 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15746 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15747 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15749 sprintf (string, "crnot %d,%d", a, b);
15753 /* Return insn for VSX or Altivec comparisons. */
15756 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15759 enum machine_mode mode = GET_MODE (op0);
15767 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15773 mask = gen_reg_rtx (mode);
15774 emit_insn (gen_rtx_SET (VOIDmode,
15776 gen_rtx_fmt_ee (code, mode, op0, op1)));
15783 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15784 DMODE is expected destination mode. This is a recursive function. */
15787 rs6000_emit_vector_compare (enum rtx_code rcode,
15789 enum machine_mode dmode)
15792 bool swap_operands = false;
15793 bool try_again = false;
15795 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15796 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15798 /* See if the comparison works as is. */
15799 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15807 swap_operands = true;
15812 swap_operands = true;
15820 /* Invert condition and try again.
15821 e.g., A != B becomes ~(A==B). */
15823 enum rtx_code rev_code;
15824 enum insn_code nor_code;
15827 rev_code = reverse_condition_maybe_unordered (rcode);
15828 if (rev_code == UNKNOWN)
15831 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15832 if (nor_code == CODE_FOR_nothing)
15835 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15839 mask = gen_reg_rtx (dmode);
15840 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15848 /* Try GT/GTU/LT/LTU OR EQ */
15851 enum insn_code ior_code;
15852 enum rtx_code new_code;
15873 gcc_unreachable ();
15876 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15877 if (ior_code == CODE_FOR_nothing)
15880 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15884 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15888 mask = gen_reg_rtx (dmode);
15889 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15907 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15912 /* You only get two chances. */
15916 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15917 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15918 operands for the relation operation COND. */
15921 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15922 rtx cond, rtx cc_op0, rtx cc_op1)
15924 enum machine_mode dest_mode = GET_MODE (dest);
15925 enum rtx_code rcode = GET_CODE (cond);
15926 enum machine_mode cc_mode = CCmode;
15930 bool invert_move = false;
15932 if (VECTOR_UNIT_NONE_P (dest_mode))
15937 /* Swap operands if we can, and fall back to doing the operation as
15938 specified, and doing a NOR to invert the test. */
15944 /* Invert condition and try again.
15945 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15946 invert_move = true;
15947 rcode = reverse_condition_maybe_unordered (rcode);
15948 if (rcode == UNKNOWN)
15952 /* Mark unsigned tests with CCUNSmode. */
15957 cc_mode = CCUNSmode;
15964 /* Get the vector mask for the given relational operations. */
15965 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15973 op_true = op_false;
15977 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15978 emit_insn (gen_rtx_SET (VOIDmode,
15980 gen_rtx_IF_THEN_ELSE (dest_mode,
15987 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15988 operands of the last comparison is nonzero/true, FALSE_COND if it
15989 is zero/false. Return 0 if the hardware has no such operation. */
15992 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15994 enum rtx_code code = GET_CODE (op);
15995 rtx op0 = XEXP (op, 0);
15996 rtx op1 = XEXP (op, 1);
15997 REAL_VALUE_TYPE c1;
15998 enum machine_mode compare_mode = GET_MODE (op0);
15999 enum machine_mode result_mode = GET_MODE (dest);
16001 bool is_against_zero;
16003 /* These modes should always match. */
16004 if (GET_MODE (op1) != compare_mode
16005 /* In the isel case however, we can use a compare immediate, so
16006 op1 may be a small constant. */
16007 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16009 if (GET_MODE (true_cond) != result_mode)
16011 if (GET_MODE (false_cond) != result_mode)
16014 /* First, work out if the hardware can do this at all, or
16015 if it's too slow.... */
16016 if (!FLOAT_MODE_P (compare_mode))
16019 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16022 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16023 && SCALAR_FLOAT_MODE_P (compare_mode))
16026 is_against_zero = op1 == CONST0_RTX (compare_mode);
16028 /* A floating-point subtract might overflow, underflow, or produce
16029 an inexact result, thus changing the floating-point flags, so it
16030 can't be generated if we care about that. It's safe if one side
16031 of the construct is zero, since then no subtract will be
16033 if (SCALAR_FLOAT_MODE_P (compare_mode)
16034 && flag_trapping_math && ! is_against_zero)
16037 /* Eliminate half of the comparisons by switching operands, this
16038 makes the remaining code simpler. */
16039 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16040 || code == LTGT || code == LT || code == UNLE)
16042 code = reverse_condition_maybe_unordered (code);
16044 true_cond = false_cond;
16048 /* UNEQ and LTGT take four instructions for a comparison with zero,
16049 it'll probably be faster to use a branch here too. */
16050 if (code == UNEQ && HONOR_NANS (compare_mode))
16053 if (GET_CODE (op1) == CONST_DOUBLE)
16054 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16056 /* We're going to try to implement comparisons by performing
16057 a subtract, then comparing against zero. Unfortunately,
16058 Inf - Inf is NaN which is not zero, and so if we don't
16059 know that the operand is finite and the comparison
16060 would treat EQ different to UNORDERED, we can't do it. */
16061 if (HONOR_INFINITIES (compare_mode)
16062 && code != GT && code != UNGE
16063 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16064 /* Constructs of the form (a OP b ? a : b) are safe. */
16065 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16066 || (! rtx_equal_p (op0, true_cond)
16067 && ! rtx_equal_p (op1, true_cond))))
16070 /* At this point we know we can use fsel. */
16072 /* Reduce the comparison to a comparison against zero. */
16073 if (! is_against_zero)
16075 temp = gen_reg_rtx (compare_mode);
16076 emit_insn (gen_rtx_SET (VOIDmode, temp,
16077 gen_rtx_MINUS (compare_mode, op0, op1)));
16079 op1 = CONST0_RTX (compare_mode);
16082 /* If we don't care about NaNs we can reduce some of the comparisons
16083 down to faster ones. */
16084 if (! HONOR_NANS (compare_mode))
16090 true_cond = false_cond;
16103 /* Now, reduce everything down to a GE. */
16110 temp = gen_reg_rtx (compare_mode);
16111 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16116 temp = gen_reg_rtx (compare_mode);
16117 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16122 temp = gen_reg_rtx (compare_mode);
16123 emit_insn (gen_rtx_SET (VOIDmode, temp,
16124 gen_rtx_NEG (compare_mode,
16125 gen_rtx_ABS (compare_mode, op0))));
16130 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16131 temp = gen_reg_rtx (result_mode);
16132 emit_insn (gen_rtx_SET (VOIDmode, temp,
16133 gen_rtx_IF_THEN_ELSE (result_mode,
16134 gen_rtx_GE (VOIDmode,
16136 true_cond, false_cond)));
16137 false_cond = true_cond;
16140 temp = gen_reg_rtx (compare_mode);
16141 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16146 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16147 temp = gen_reg_rtx (result_mode);
16148 emit_insn (gen_rtx_SET (VOIDmode, temp,
16149 gen_rtx_IF_THEN_ELSE (result_mode,
16150 gen_rtx_GE (VOIDmode,
16152 true_cond, false_cond)));
16153 true_cond = false_cond;
16156 temp = gen_reg_rtx (compare_mode);
16157 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16162 gcc_unreachable ();
16165 emit_insn (gen_rtx_SET (VOIDmode, dest,
16166 gen_rtx_IF_THEN_ELSE (result_mode,
16167 gen_rtx_GE (VOIDmode,
16169 true_cond, false_cond)));
16173 /* Same as above, but for ints (isel). */
16176 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16178 rtx condition_rtx, cr;
16179 enum machine_mode mode = GET_MODE (dest);
16181 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16184 /* We still have to do the compare, because isel doesn't do a
16185 compare, it just looks at the CRx bits set by a previous compare
16187 condition_rtx = rs6000_generate_compare (op, mode);
16188 cr = XEXP (condition_rtx, 0);
16190 if (mode == SImode)
16192 if (GET_MODE (cr) == CCmode)
16193 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16194 true_cond, false_cond, cr));
16196 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16197 true_cond, false_cond, cr));
16201 if (GET_MODE (cr) == CCmode)
16202 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16203 true_cond, false_cond, cr));
16205 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16206 true_cond, false_cond, cr));
16213 output_isel (rtx *operands)
16215 enum rtx_code code;
16217 code = GET_CODE (operands[1]);
16218 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16220 PUT_CODE (operands[1], reverse_condition (code));
16221 return "isel %0,%3,%2,%j1";
16224 return "isel %0,%2,%3,%j1";
16228 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16230 enum machine_mode mode = GET_MODE (op0);
16234 /* VSX/altivec have direct min/max insns. */
16235 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16237 emit_insn (gen_rtx_SET (VOIDmode,
16239 gen_rtx_fmt_ee (code, mode, op0, op1)));
16243 if (code == SMAX || code == SMIN)
16248 if (code == SMAX || code == UMAX)
16249 target = emit_conditional_move (dest, c, op0, op1, mode,
16250 op0, op1, mode, 0);
16252 target = emit_conditional_move (dest, c, op0, op1, mode,
16253 op1, op0, mode, 0);
16254 gcc_assert (target);
16255 if (target != dest)
16256 emit_move_insn (dest, target);
16259 /* Emit instructions to perform a load-reserved/store-conditional operation.
16260 The operation performed is an atomic
16261 (set M (CODE:MODE M OP))
16262 If not NULL, BEFORE is atomically set to M before the operation, and
16263 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16264 If SYNC_P then a memory barrier is emitted before the operation.
16265 Either OP or M may be wrapped in a NOT operation. */
16268 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16269 rtx m, rtx op, rtx before_param, rtx after_param,
16272 enum machine_mode used_mode;
16273 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16276 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16277 rtx shift = NULL_RTX;
16280 emit_insn (gen_lwsync ());
16284 /* If this is smaller than SImode, we'll have to use SImode with
16286 if (mode == QImode || mode == HImode)
16290 if (MEM_ALIGN (used_m) >= 32)
16293 if (BYTES_BIG_ENDIAN)
16294 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16296 shift = GEN_INT (ishift);
16297 used_m = change_address (used_m, SImode, 0);
16301 rtx addrSI, aligned_addr;
16302 int shift_mask = mode == QImode ? 0x18 : 0x10;
16304 addrSI = gen_lowpart_common (SImode,
16305 force_reg (Pmode, XEXP (used_m, 0)));
16306 addrSI = force_reg (SImode, addrSI);
16307 shift = gen_reg_rtx (SImode);
16309 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16310 GEN_INT (shift_mask)));
16311 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16313 aligned_addr = expand_binop (Pmode, and_optab,
16315 GEN_INT (-4), NULL_RTX,
16316 1, OPTAB_LIB_WIDEN);
16317 used_m = change_address (used_m, SImode, aligned_addr);
16318 set_mem_align (used_m, 32);
16320 /* It's safe to keep the old alias set of USED_M, because
16321 the operation is atomic and only affects the original
16325 if (GET_CODE (op) == NOT)
16327 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16328 oldop = gen_rtx_NOT (SImode, oldop);
16331 oldop = lowpart_subreg (SImode, op, mode);
16337 newop = expand_binop (SImode, and_optab,
16338 oldop, GEN_INT (imask), NULL_RTX,
16339 1, OPTAB_LIB_WIDEN);
16340 emit_insn (gen_ashlsi3 (newop, newop, shift));
16343 case NOT: /* NAND */
16344 newop = expand_binop (SImode, ior_optab,
16345 oldop, GEN_INT (~imask), NULL_RTX,
16346 1, OPTAB_LIB_WIDEN);
16347 emit_insn (gen_rotlsi3 (newop, newop, shift));
16351 newop = expand_binop (SImode, ior_optab,
16352 oldop, GEN_INT (~imask), NULL_RTX,
16353 1, OPTAB_LIB_WIDEN);
16354 emit_insn (gen_rotlsi3 (newop, newop, shift));
16362 newop = expand_binop (SImode, and_optab,
16363 oldop, GEN_INT (imask), NULL_RTX,
16364 1, OPTAB_LIB_WIDEN);
16365 emit_insn (gen_ashlsi3 (newop, newop, shift));
16367 mask = gen_reg_rtx (SImode);
16368 emit_move_insn (mask, GEN_INT (imask));
16369 emit_insn (gen_ashlsi3 (mask, mask, shift));
16372 newop = gen_rtx_PLUS (SImode, m, newop);
16374 newop = gen_rtx_MINUS (SImode, m, newop);
16375 newop = gen_rtx_AND (SImode, newop, mask);
16376 newop = gen_rtx_IOR (SImode, newop,
16377 gen_rtx_AND (SImode,
16378 gen_rtx_NOT (SImode, mask),
16384 gcc_unreachable ();
16388 used_mode = SImode;
16389 before = gen_reg_rtx (used_mode);
16390 after = gen_reg_rtx (used_mode);
16395 before = before_param;
16396 after = after_param;
16398 if (before == NULL_RTX)
16399 before = gen_reg_rtx (used_mode);
16400 if (after == NULL_RTX)
16401 after = gen_reg_rtx (used_mode);
16404 if ((code == PLUS || code == MINUS)
16405 && used_mode != mode)
16406 the_op = op; /* Computed above. */
16407 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16408 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16409 else if (code == NOT)
16410 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16411 gen_rtx_NOT (used_mode, m),
16412 gen_rtx_NOT (used_mode, op));
16414 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16416 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16417 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16418 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16419 gen_rtx_UNSPEC (used_mode,
16420 gen_rtvec (1, the_op),
16422 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16424 if ((code == PLUS || code == MINUS) && used_mode != mode)
16425 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16426 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16428 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16429 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16431 /* Shift and mask the return values properly. */
16432 if (used_mode != mode && before_param)
16434 emit_insn (gen_lshrsi3 (before, before, shift));
16435 convert_move (before_param, before, 1);
16438 if (used_mode != mode && after_param)
16440 emit_insn (gen_lshrsi3 (after, after, shift));
16441 convert_move (after_param, after, 1);
16444 /* The previous sequence will end with a branch that's dependent on
16445 the conditional store, so placing an isync will ensure that no
16446 other instructions (especially, no load or store instructions)
16447 can start before the atomic operation completes. */
16449 emit_insn (gen_isync ());
16452 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16453 COND is true. Mark the jump as unlikely to be taken. */
16456 emit_unlikely_jump (rtx cond, rtx label)
16458 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16461 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16462 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16463 add_reg_note (x, REG_BR_PROB, very_unlikely);
16466 /* A subroutine of the atomic operation splitters. Emit a load-locked
16467 instruction in MODE. */
16470 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16472 rtx (*fn) (rtx, rtx) = NULL;
16473 if (mode == SImode)
16474 fn = gen_load_locked_si;
16475 else if (mode == DImode)
16476 fn = gen_load_locked_di;
16477 emit_insn (fn (reg, mem));
16480 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16481 instruction in MODE. */
16484 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16486 rtx (*fn) (rtx, rtx, rtx) = NULL;
16487 if (mode == SImode)
16488 fn = gen_store_conditional_si;
16489 else if (mode == DImode)
16490 fn = gen_store_conditional_di;
16492 /* Emit sync before stwcx. to address PPC405 Erratum. */
16493 if (PPC405_ERRATUM77)
16494 emit_insn (gen_memory_barrier ());
16496 emit_insn (fn (res, mem, val));
16499 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16500 to perform. MEM is the memory on which to operate. VAL is the second
16501 operand of the binary operator. BEFORE and AFTER are optional locations to
16502 return the value of MEM either before of after the operation. SCRATCH is
16503 a scratch register. */
16506 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16507 rtx before, rtx after, rtx scratch)
16509 enum machine_mode mode = GET_MODE (mem);
16510 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16512 emit_insn (gen_lwsync ());
16514 label = gen_label_rtx ();
16515 emit_label (label);
16516 label = gen_rtx_LABEL_REF (VOIDmode, label);
16518 if (before == NULL_RTX)
16520 emit_load_locked (mode, before, mem);
16523 x = gen_rtx_IOR (mode,
16524 gen_rtx_NOT (mode, before),
16525 gen_rtx_NOT (mode, val));
16526 else if (code == AND)
16527 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16529 x = gen_rtx_fmt_ee (code, mode, before, val);
16531 if (after != NULL_RTX)
16532 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16533 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16535 emit_store_conditional (mode, cond, mem, scratch);
16537 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16538 emit_unlikely_jump (x, label);
16540 emit_insn (gen_isync ());
16543 /* Expand an atomic compare and swap operation. MEM is the memory on which
16544 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16545 value to be stored. SCRATCH is a scratch GPR. */
16548 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16551 enum machine_mode mode = GET_MODE (mem);
16552 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16554 emit_insn (gen_lwsync ());
16556 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16557 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16558 emit_label (XEXP (label1, 0));
16560 emit_load_locked (mode, retval, mem);
16562 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16563 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16565 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16566 emit_unlikely_jump (x, label2);
16568 emit_move_insn (scratch, newval);
16569 emit_store_conditional (mode, cond, mem, scratch);
16571 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16572 emit_unlikely_jump (x, label1);
16574 emit_insn (gen_isync ());
16575 emit_label (XEXP (label2, 0));
16578 /* Expand an atomic test and set operation. MEM is the memory on which
16579 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16582 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16584 enum machine_mode mode = GET_MODE (mem);
16585 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16587 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16588 emit_label (XEXP (label, 0));
16590 emit_load_locked (mode, retval, mem);
16591 emit_move_insn (scratch, val);
16592 emit_store_conditional (mode, cond, mem, scratch);
16594 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16595 emit_unlikely_jump (x, label);
16597 emit_insn (gen_isync ());
16601 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16603 enum machine_mode mode = GET_MODE (mem);
16604 rtx addrSI, align, wdst, shift, mask;
16605 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16606 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16608 /* Shift amount for subword relative to aligned word. */
16609 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16610 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16611 shift = gen_reg_rtx (SImode);
16612 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16613 GEN_INT (shift_mask)));
16614 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16616 /* Shift and mask old value into position within word. */
16617 oldval = convert_modes (SImode, mode, oldval, 1);
16618 oldval = expand_binop (SImode, and_optab,
16619 oldval, GEN_INT (imask), NULL_RTX,
16620 1, OPTAB_LIB_WIDEN);
16621 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16623 /* Shift and mask new value into position within word. */
16624 newval = convert_modes (SImode, mode, newval, 1);
16625 newval = expand_binop (SImode, and_optab,
16626 newval, GEN_INT (imask), NULL_RTX,
16627 1, OPTAB_LIB_WIDEN);
16628 emit_insn (gen_ashlsi3 (newval, newval, shift));
16630 /* Mask for insertion. */
16631 mask = gen_reg_rtx (SImode);
16632 emit_move_insn (mask, GEN_INT (imask));
16633 emit_insn (gen_ashlsi3 (mask, mask, shift));
16635 /* Address of aligned word containing subword. */
16636 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16637 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16638 mem = change_address (mem, SImode, align);
16639 set_mem_align (mem, 32);
16640 MEM_VOLATILE_P (mem) = 1;
16642 wdst = gen_reg_rtx (SImode);
16643 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16644 oldval, newval, mem));
16646 /* Shift the result back. */
16647 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16649 emit_move_insn (dst, gen_lowpart (mode, wdst));
16653 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16654 rtx oldval, rtx newval, rtx mem,
16657 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16659 emit_insn (gen_lwsync ());
16660 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16661 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16662 emit_label (XEXP (label1, 0));
16664 emit_load_locked (SImode, scratch, mem);
16666 /* Mask subword within loaded value for comparison with oldval.
16667 Use UNSPEC_AND to avoid clobber.*/
16668 emit_insn (gen_rtx_SET (SImode, dest,
16669 gen_rtx_UNSPEC (SImode,
16670 gen_rtvec (2, scratch, mask),
16673 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16674 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16676 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16677 emit_unlikely_jump (x, label2);
16679 /* Clear subword within loaded value for insertion of new value. */
16680 emit_insn (gen_rtx_SET (SImode, scratch,
16681 gen_rtx_AND (SImode,
16682 gen_rtx_NOT (SImode, mask), scratch)));
16683 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16684 emit_store_conditional (SImode, cond, mem, scratch);
16686 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16687 emit_unlikely_jump (x, label1);
16689 emit_insn (gen_isync ());
16690 emit_label (XEXP (label2, 0));
16694 /* Emit instructions to move SRC to DST. Called by splitters for
16695 multi-register moves. It will emit at most one instruction for
16696 each register that is accessed; that is, it won't emit li/lis pairs
16697 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16701 rs6000_split_multireg_move (rtx dst, rtx src)
16703 /* The register number of the first register being moved. */
16705 /* The mode that is to be moved. */
16706 enum machine_mode mode;
16707 /* The mode that the move is being done in, and its size. */
16708 enum machine_mode reg_mode;
16710 /* The number of registers that will be moved. */
16713 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16714 mode = GET_MODE (dst);
16715 nregs = hard_regno_nregs[reg][mode];
16716 if (FP_REGNO_P (reg))
16717 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16718 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16719 else if (ALTIVEC_REGNO_P (reg))
16720 reg_mode = V16QImode;
16721 else if (TARGET_E500_DOUBLE && mode == TFmode)
16724 reg_mode = word_mode;
16725 reg_mode_size = GET_MODE_SIZE (reg_mode);
16727 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16729 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16731 /* Move register range backwards, if we might have destructive
16734 for (i = nregs - 1; i >= 0; i--)
16735 emit_insn (gen_rtx_SET (VOIDmode,
16736 simplify_gen_subreg (reg_mode, dst, mode,
16737 i * reg_mode_size),
16738 simplify_gen_subreg (reg_mode, src, mode,
16739 i * reg_mode_size)));
16745 bool used_update = false;
16747 if (MEM_P (src) && INT_REGNO_P (reg))
16751 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16752 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16755 breg = XEXP (XEXP (src, 0), 0);
16756 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16757 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16758 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16759 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16760 src = replace_equiv_address (src, breg);
16762 else if (! rs6000_offsettable_memref_p (src))
16765 basereg = gen_rtx_REG (Pmode, reg);
16766 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16767 src = replace_equiv_address (src, basereg);
16770 breg = XEXP (src, 0);
16771 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16772 breg = XEXP (breg, 0);
16774 /* If the base register we are using to address memory is
16775 also a destination reg, then change that register last. */
16777 && REGNO (breg) >= REGNO (dst)
16778 && REGNO (breg) < REGNO (dst) + nregs)
16779 j = REGNO (breg) - REGNO (dst);
16782 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16786 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16787 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16790 breg = XEXP (XEXP (dst, 0), 0);
16791 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16792 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16793 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16795 /* We have to update the breg before doing the store.
16796 Use store with update, if available. */
16800 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16801 emit_insn (TARGET_32BIT
16802 ? (TARGET_POWERPC64
16803 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16804 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16805 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16806 used_update = true;
16809 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16810 dst = replace_equiv_address (dst, breg);
16813 gcc_assert (rs6000_offsettable_memref_p (dst));
16816 for (i = 0; i < nregs; i++)
16818 /* Calculate index to next subword. */
16823 /* If compiler already emitted move of first word by
16824 store with update, no need to do anything. */
16825 if (j == 0 && used_update)
16828 emit_insn (gen_rtx_SET (VOIDmode,
16829 simplify_gen_subreg (reg_mode, dst, mode,
16830 j * reg_mode_size),
16831 simplify_gen_subreg (reg_mode, src, mode,
16832 j * reg_mode_size)));
16838 /* This page contains routines that are used to determine what the
16839 function prologue and epilogue code will do and write them out. */
16841 /* Return the first fixed-point register that is required to be
16842 saved. 32 if none. */
16845 first_reg_to_save (void)
16849 /* Find lowest numbered live register. */
16850 for (first_reg = 13; first_reg <= 31; first_reg++)
16851 if (df_regs_ever_live_p (first_reg)
16852 && (! call_used_regs[first_reg]
16853 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16854 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16855 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16856 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16861 && crtl->uses_pic_offset_table
16862 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16863 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16869 /* Similar, for FP regs. */
16872 first_fp_reg_to_save (void)
16876 /* Find lowest numbered live register. */
16877 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16878 if (df_regs_ever_live_p (first_reg))
16884 /* Similar, for AltiVec regs. */
16887 first_altivec_reg_to_save (void)
16891 /* Stack frame remains as is unless we are in AltiVec ABI. */
16892 if (! TARGET_ALTIVEC_ABI)
16893 return LAST_ALTIVEC_REGNO + 1;
16895 /* On Darwin, the unwind routines are compiled without
16896 TARGET_ALTIVEC, and use save_world to save/restore the
16897 altivec registers when necessary. */
16898 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16899 && ! TARGET_ALTIVEC)
16900 return FIRST_ALTIVEC_REGNO + 20;
16902 /* Find lowest numbered live register. */
16903 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16904 if (df_regs_ever_live_p (i))
16910 /* Return a 32-bit mask of the AltiVec registers we need to set in
16911 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16912 the 32-bit word is 0. */
16914 static unsigned int
16915 compute_vrsave_mask (void)
16917 unsigned int i, mask = 0;
16919 /* On Darwin, the unwind routines are compiled without
16920 TARGET_ALTIVEC, and use save_world to save/restore the
16921 call-saved altivec registers when necessary. */
16922 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16923 && ! TARGET_ALTIVEC)
16926 /* First, find out if we use _any_ altivec registers. */
16927 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16928 if (df_regs_ever_live_p (i))
16929 mask |= ALTIVEC_REG_BIT (i);
16934 /* Next, remove the argument registers from the set. These must
16935 be in the VRSAVE mask set by the caller, so we don't need to add
16936 them in again. More importantly, the mask we compute here is
16937 used to generate CLOBBERs in the set_vrsave insn, and we do not
16938 wish the argument registers to die. */
16939 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16940 mask &= ~ALTIVEC_REG_BIT (i);
16942 /* Similarly, remove the return value from the set. */
16945 diddle_return_value (is_altivec_return_reg, &yes);
16947 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16953 /* For a very restricted set of circumstances, we can cut down the
16954 size of prologues/epilogues by calling our own save/restore-the-world
16958 compute_save_world_info (rs6000_stack_t *info_ptr)
16960 info_ptr->world_save_p = 1;
16961 info_ptr->world_save_p
16962 = (WORLD_SAVE_P (info_ptr)
16963 && DEFAULT_ABI == ABI_DARWIN
16964 && ! (cfun->calls_setjmp && flag_exceptions)
16965 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16966 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16967 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16968 && info_ptr->cr_save_p);
16970 /* This will not work in conjunction with sibcalls. Make sure there
16971 are none. (This check is expensive, but seldom executed.) */
16972 if (WORLD_SAVE_P (info_ptr))
16975 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16976 if ( GET_CODE (insn) == CALL_INSN
16977 && SIBLING_CALL_P (insn))
16979 info_ptr->world_save_p = 0;
16984 if (WORLD_SAVE_P (info_ptr))
16986 /* Even if we're not touching VRsave, make sure there's room on the
16987 stack for it, if it looks like we're calling SAVE_WORLD, which
16988 will attempt to save it. */
16989 info_ptr->vrsave_size = 4;
16991 /* If we are going to save the world, we need to save the link register too. */
16992 info_ptr->lr_save_p = 1;
16994 /* "Save" the VRsave register too if we're saving the world. */
16995 if (info_ptr->vrsave_mask == 0)
16996 info_ptr->vrsave_mask = compute_vrsave_mask ();
16998 /* Because the Darwin register save/restore routines only handle
16999 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17001 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17002 && (info_ptr->first_altivec_reg_save
17003 >= FIRST_SAVED_ALTIVEC_REGNO));
17010 is_altivec_return_reg (rtx reg, void *xyes)
17012 bool *yes = (bool *) xyes;
17013 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17018 /* Calculate the stack information for the current function. This is
17019 complicated by having two separate calling sequences, the AIX calling
17020 sequence and the V.4 calling sequence.
17022 AIX (and Darwin/Mac OS X) stack frames look like:
17024 SP----> +---------------------------------------+
17025 | back chain to caller | 0 0
17026 +---------------------------------------+
17027 | saved CR | 4 8 (8-11)
17028 +---------------------------------------+
17030 +---------------------------------------+
17031 | reserved for compilers | 12 24
17032 +---------------------------------------+
17033 | reserved for binders | 16 32
17034 +---------------------------------------+
17035 | saved TOC pointer | 20 40
17036 +---------------------------------------+
17037 | Parameter save area (P) | 24 48
17038 +---------------------------------------+
17039 | Alloca space (A) | 24+P etc.
17040 +---------------------------------------+
17041 | Local variable space (L) | 24+P+A
17042 +---------------------------------------+
17043 | Float/int conversion temporary (X) | 24+P+A+L
17044 +---------------------------------------+
17045 | Save area for AltiVec registers (W) | 24+P+A+L+X
17046 +---------------------------------------+
17047 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17048 +---------------------------------------+
17049 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17050 +---------------------------------------+
17051 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17052 +---------------------------------------+
17053 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17054 +---------------------------------------+
17055 old SP->| back chain to caller's caller |
17056 +---------------------------------------+
17058 The required alignment for AIX configurations is two words (i.e., 8
17062 V.4 stack frames look like:
17064 SP----> +---------------------------------------+
17065 | back chain to caller | 0
17066 +---------------------------------------+
17067 | caller's saved LR | 4
17068 +---------------------------------------+
17069 | Parameter save area (P) | 8
17070 +---------------------------------------+
17071 | Alloca space (A) | 8+P
17072 +---------------------------------------+
17073 | Varargs save area (V) | 8+P+A
17074 +---------------------------------------+
17075 | Local variable space (L) | 8+P+A+V
17076 +---------------------------------------+
17077 | Float/int conversion temporary (X) | 8+P+A+V+L
17078 +---------------------------------------+
17079 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17080 +---------------------------------------+
17081 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17082 +---------------------------------------+
17083 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17084 +---------------------------------------+
17085 | SPE: area for 64-bit GP registers |
17086 +---------------------------------------+
17087 | SPE alignment padding |
17088 +---------------------------------------+
17089 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17090 +---------------------------------------+
17091 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17092 +---------------------------------------+
17093 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17094 +---------------------------------------+
17095 old SP->| back chain to caller's caller |
17096 +---------------------------------------+
17098 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17099 given. (But note below and in sysv4.h that we require only 8 and
17100 may round up the size of our stack frame anyways. The historical
17101 reason is early versions of powerpc-linux which didn't properly
17102 align the stack at program startup. A happy side-effect is that
17103 -mno-eabi libraries can be used with -meabi programs.)
17105 The EABI configuration defaults to the V.4 layout. However,
17106 the stack alignment requirements may differ. If -mno-eabi is not
17107 given, the required stack alignment is 8 bytes; if -mno-eabi is
17108 given, the required alignment is 16 bytes. (But see V.4 comment
17111 #ifndef ABI_STACK_BOUNDARY
17112 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17115 static rs6000_stack_t *
17116 rs6000_stack_info (void)
17118 static rs6000_stack_t info;
17119 rs6000_stack_t *info_ptr = &info;
17120 int reg_size = TARGET_32BIT ? 4 : 8;
17124 HOST_WIDE_INT non_fixed_size;
17126 memset (&info, 0, sizeof (info));
17130 /* Cache value so we don't rescan instruction chain over and over. */
17131 if (cfun->machine->insn_chain_scanned_p == 0)
17132 cfun->machine->insn_chain_scanned_p
17133 = spe_func_has_64bit_regs_p () + 1;
17134 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17137 /* Select which calling sequence. */
17138 info_ptr->abi = DEFAULT_ABI;
17140 /* Calculate which registers need to be saved & save area size. */
17141 info_ptr->first_gp_reg_save = first_reg_to_save ();
17142 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17143 even if it currently looks like we won't. Reload may need it to
17144 get at a constant; if so, it will have already created a constant
17145 pool entry for it. */
17146 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17147 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17148 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17149 && crtl->uses_const_pool
17150 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17151 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17153 first_gp = info_ptr->first_gp_reg_save;
17155 info_ptr->gp_size = reg_size * (32 - first_gp);
17157 /* For the SPE, we have an additional upper 32-bits on each GPR.
17158 Ideally we should save the entire 64-bits only when the upper
17159 half is used in SIMD instructions. Since we only record
17160 registers live (not the size they are used in), this proves
17161 difficult because we'd have to traverse the instruction chain at
17162 the right time, taking reload into account. This is a real pain,
17163 so we opt to save the GPRs in 64-bits always if but one register
17164 gets used in 64-bits. Otherwise, all the registers in the frame
17165 get saved in 32-bits.
17167 So... since when we save all GPRs (except the SP) in 64-bits, the
17168 traditional GP save area will be empty. */
17169 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17170 info_ptr->gp_size = 0;
17172 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17173 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17175 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17176 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17177 - info_ptr->first_altivec_reg_save);
17179 /* Does this function call anything? */
17180 info_ptr->calls_p = (! current_function_is_leaf
17181 || cfun->machine->ra_needs_full_frame);
17183 /* Determine if we need to save the link register. */
17184 if ((DEFAULT_ABI == ABI_AIX
17186 && !TARGET_PROFILE_KERNEL)
17187 #ifdef TARGET_RELOCATABLE
17188 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17190 || (info_ptr->first_fp_reg_save != 64
17191 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17192 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17193 || info_ptr->calls_p
17194 || rs6000_ra_ever_killed ())
17196 info_ptr->lr_save_p = 1;
17197 df_set_regs_ever_live (LR_REGNO, true);
17200 /* Determine if we need to save the condition code registers. */
17201 if (df_regs_ever_live_p (CR2_REGNO)
17202 || df_regs_ever_live_p (CR3_REGNO)
17203 || df_regs_ever_live_p (CR4_REGNO))
17205 info_ptr->cr_save_p = 1;
17206 if (DEFAULT_ABI == ABI_V4)
17207 info_ptr->cr_size = reg_size;
17210 /* If the current function calls __builtin_eh_return, then we need
17211 to allocate stack space for registers that will hold data for
17212 the exception handler. */
17213 if (crtl->calls_eh_return)
17216 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17219 /* SPE saves EH registers in 64-bits. */
17220 ehrd_size = i * (TARGET_SPE_ABI
17221 && info_ptr->spe_64bit_regs_used != 0
17222 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17227 /* Determine various sizes. */
17228 info_ptr->reg_size = reg_size;
17229 info_ptr->fixed_size = RS6000_SAVE_AREA;
17230 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17231 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17232 TARGET_ALTIVEC ? 16 : 8);
17233 if (FRAME_GROWS_DOWNWARD)
17234 info_ptr->vars_size
17235 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17236 + info_ptr->parm_size,
17237 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17238 - (info_ptr->fixed_size + info_ptr->vars_size
17239 + info_ptr->parm_size);
17241 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17242 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17244 info_ptr->spe_gp_size = 0;
17246 if (TARGET_ALTIVEC_ABI)
17247 info_ptr->vrsave_mask = compute_vrsave_mask ();
17249 info_ptr->vrsave_mask = 0;
17251 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17252 info_ptr->vrsave_size = 4;
17254 info_ptr->vrsave_size = 0;
17256 compute_save_world_info (info_ptr);
17258 /* Calculate the offsets. */
17259 switch (DEFAULT_ABI)
17263 gcc_unreachable ();
17267 info_ptr->fp_save_offset = - info_ptr->fp_size;
17268 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17270 if (TARGET_ALTIVEC_ABI)
17272 info_ptr->vrsave_save_offset
17273 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17275 /* Align stack so vector save area is on a quadword boundary.
17276 The padding goes above the vectors. */
17277 if (info_ptr->altivec_size != 0)
17278 info_ptr->altivec_padding_size
17279 = info_ptr->vrsave_save_offset & 0xF;
17281 info_ptr->altivec_padding_size = 0;
17283 info_ptr->altivec_save_offset
17284 = info_ptr->vrsave_save_offset
17285 - info_ptr->altivec_padding_size
17286 - info_ptr->altivec_size;
17287 gcc_assert (info_ptr->altivec_size == 0
17288 || info_ptr->altivec_save_offset % 16 == 0);
17290 /* Adjust for AltiVec case. */
17291 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17294 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17295 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17296 info_ptr->lr_save_offset = 2*reg_size;
17300 info_ptr->fp_save_offset = - info_ptr->fp_size;
17301 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17302 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17304 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17306 /* Align stack so SPE GPR save area is aligned on a
17307 double-word boundary. */
17308 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17309 info_ptr->spe_padding_size
17310 = 8 - (-info_ptr->cr_save_offset % 8);
17312 info_ptr->spe_padding_size = 0;
17314 info_ptr->spe_gp_save_offset
17315 = info_ptr->cr_save_offset
17316 - info_ptr->spe_padding_size
17317 - info_ptr->spe_gp_size;
17319 /* Adjust for SPE case. */
17320 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17322 else if (TARGET_ALTIVEC_ABI)
17324 info_ptr->vrsave_save_offset
17325 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17327 /* Align stack so vector save area is on a quadword boundary. */
17328 if (info_ptr->altivec_size != 0)
17329 info_ptr->altivec_padding_size
17330 = 16 - (-info_ptr->vrsave_save_offset % 16);
17332 info_ptr->altivec_padding_size = 0;
17334 info_ptr->altivec_save_offset
17335 = info_ptr->vrsave_save_offset
17336 - info_ptr->altivec_padding_size
17337 - info_ptr->altivec_size;
17339 /* Adjust for AltiVec case. */
17340 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17343 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17344 info_ptr->ehrd_offset -= ehrd_size;
17345 info_ptr->lr_save_offset = reg_size;
17349 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17350 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17351 + info_ptr->gp_size
17352 + info_ptr->altivec_size
17353 + info_ptr->altivec_padding_size
17354 + info_ptr->spe_gp_size
17355 + info_ptr->spe_padding_size
17357 + info_ptr->cr_size
17358 + info_ptr->vrsave_size,
17361 non_fixed_size = (info_ptr->vars_size
17362 + info_ptr->parm_size
17363 + info_ptr->save_size);
17365 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17366 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17368 /* Determine if we need to allocate any stack frame:
17370 For AIX we need to push the stack if a frame pointer is needed
17371 (because the stack might be dynamically adjusted), if we are
17372 debugging, if we make calls, or if the sum of fp_save, gp_save,
17373 and local variables are more than the space needed to save all
17374 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17375 + 18*8 = 288 (GPR13 reserved).
17377 For V.4 we don't have the stack cushion that AIX uses, but assume
17378 that the debugger can handle stackless frames. */
17380 if (info_ptr->calls_p)
17381 info_ptr->push_p = 1;
17383 else if (DEFAULT_ABI == ABI_V4)
17384 info_ptr->push_p = non_fixed_size != 0;
17386 else if (frame_pointer_needed)
17387 info_ptr->push_p = 1;
17389 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17390 info_ptr->push_p = 1;
17393 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17395 /* Zero offsets if we're not saving those registers. */
17396 if (info_ptr->fp_size == 0)
17397 info_ptr->fp_save_offset = 0;
17399 if (info_ptr->gp_size == 0)
17400 info_ptr->gp_save_offset = 0;
17402 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17403 info_ptr->altivec_save_offset = 0;
17405 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17406 info_ptr->vrsave_save_offset = 0;
17408 if (! TARGET_SPE_ABI
17409 || info_ptr->spe_64bit_regs_used == 0
17410 || info_ptr->spe_gp_size == 0)
17411 info_ptr->spe_gp_save_offset = 0;
17413 if (! info_ptr->lr_save_p)
17414 info_ptr->lr_save_offset = 0;
17416 if (! info_ptr->cr_save_p)
17417 info_ptr->cr_save_offset = 0;
17422 /* Return true if the current function uses any GPRs in 64-bit SIMD
17426 spe_func_has_64bit_regs_p (void)
17430 /* Functions that save and restore all the call-saved registers will
17431 need to save/restore the registers in 64-bits. */
17432 if (crtl->calls_eh_return
17433 || cfun->calls_setjmp
17434 || crtl->has_nonlocal_goto)
17437 insns = get_insns ();
17439 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17445 /* FIXME: This should be implemented with attributes...
17447 (set_attr "spe64" "true")....then,
17448 if (get_spe64(insn)) return true;
17450 It's the only reliable way to do the stuff below. */
17452 i = PATTERN (insn);
17453 if (GET_CODE (i) == SET)
17455 enum machine_mode mode = GET_MODE (SET_SRC (i));
17457 if (SPE_VECTOR_MODE (mode))
17459 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17469 debug_stack_info (rs6000_stack_t *info)
17471 const char *abi_string;
17474 info = rs6000_stack_info ();
17476 fprintf (stderr, "\nStack information for function %s:\n",
17477 ((current_function_decl && DECL_NAME (current_function_decl))
17478 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17483 default: abi_string = "Unknown"; break;
17484 case ABI_NONE: abi_string = "NONE"; break;
17485 case ABI_AIX: abi_string = "AIX"; break;
17486 case ABI_DARWIN: abi_string = "Darwin"; break;
17487 case ABI_V4: abi_string = "V.4"; break;
17490 fprintf (stderr, "\tABI = %5s\n", abi_string);
17492 if (TARGET_ALTIVEC_ABI)
17493 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17495 if (TARGET_SPE_ABI)
17496 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17498 if (info->first_gp_reg_save != 32)
17499 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17501 if (info->first_fp_reg_save != 64)
17502 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17504 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17505 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17506 info->first_altivec_reg_save);
17508 if (info->lr_save_p)
17509 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17511 if (info->cr_save_p)
17512 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17514 if (info->vrsave_mask)
17515 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17518 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17521 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17523 if (info->gp_save_offset)
17524 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17526 if (info->fp_save_offset)
17527 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17529 if (info->altivec_save_offset)
17530 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17531 info->altivec_save_offset);
17533 if (info->spe_gp_save_offset)
17534 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17535 info->spe_gp_save_offset);
17537 if (info->vrsave_save_offset)
17538 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17539 info->vrsave_save_offset);
17541 if (info->lr_save_offset)
17542 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17544 if (info->cr_save_offset)
17545 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17547 if (info->varargs_save_offset)
17548 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17550 if (info->total_size)
17551 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17554 if (info->vars_size)
17555 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17558 if (info->parm_size)
17559 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17561 if (info->fixed_size)
17562 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17565 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17567 if (info->spe_gp_size)
17568 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17571 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17573 if (info->altivec_size)
17574 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17576 if (info->vrsave_size)
17577 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17579 if (info->altivec_padding_size)
17580 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17581 info->altivec_padding_size);
17583 if (info->spe_padding_size)
17584 fprintf (stderr, "\tspe_padding_size = %5d\n",
17585 info->spe_padding_size);
17588 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17590 if (info->save_size)
17591 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17593 if (info->reg_size != 4)
17594 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17596 fprintf (stderr, "\n");
17600 rs6000_return_addr (int count, rtx frame)
17602 /* Currently we don't optimize very well between prolog and body
17603 code and for PIC code the code can be actually quite bad, so
17604 don't try to be too clever here. */
17605 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17607 cfun->machine->ra_needs_full_frame = 1;
17614 plus_constant (copy_to_reg
17615 (gen_rtx_MEM (Pmode,
17616 memory_address (Pmode, frame))),
17617 RETURN_ADDRESS_OFFSET)));
17620 cfun->machine->ra_need_lr = 1;
17621 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17624 /* Say whether a function is a candidate for sibcall handling or not.
17625 We do not allow indirect calls to be optimized into sibling calls.
17626 Also, we can't do it if there are any vector parameters; there's
17627 nowhere to put the VRsave code so it works; note that functions with
17628 vector parameters are required to have a prototype, so the argument
17629 type info must be available here. (The tail recursion case can work
17630 with vector parameters, but there's no way to distinguish here.) */
17632 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17637 if (TARGET_ALTIVEC_VRSAVE)
17639 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17640 type; type = TREE_CHAIN (type))
17642 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17646 if (DEFAULT_ABI == ABI_DARWIN
17647 || ((*targetm.binds_local_p) (decl)
17648 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17650 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17652 if (!lookup_attribute ("longcall", attr_list)
17653 || lookup_attribute ("shortcall", attr_list))
17660 /* NULL if INSN insn is valid within a low-overhead loop.
17661 Otherwise return why doloop cannot be applied.
17662 PowerPC uses the COUNT register for branch on table instructions. */
17664 static const char *
17665 rs6000_invalid_within_doloop (const_rtx insn)
17668 return "Function call in the loop.";
17671 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17672 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17673 return "Computed branch in the loop.";
17679 rs6000_ra_ever_killed (void)
17685 if (cfun->is_thunk)
17688 /* regs_ever_live has LR marked as used if any sibcalls are present,
17689 but this should not force saving and restoring in the
17690 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17691 clobbers LR, so that is inappropriate. */
17693 /* Also, the prologue can generate a store into LR that
17694 doesn't really count, like this:
17697 bcl to set PIC register
17701 When we're called from the epilogue, we need to avoid counting
17702 this as a store. */
17704 push_topmost_sequence ();
17705 top = get_insns ();
17706 pop_topmost_sequence ();
17707 reg = gen_rtx_REG (Pmode, LR_REGNO);
17709 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17715 if (!SIBLING_CALL_P (insn))
17718 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17720 else if (set_of (reg, insn) != NULL_RTX
17721 && !prologue_epilogue_contains (insn))
17728 /* Emit instructions needed to load the TOC register.
17729 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17730 a constant pool; or for SVR4 -fpic. */
17733 rs6000_emit_load_toc_table (int fromprolog)
17736 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17738 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17741 rtx lab, tmp1, tmp2, got;
17743 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17744 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17746 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17748 got = rs6000_got_sym ();
17749 tmp1 = tmp2 = dest;
17752 tmp1 = gen_reg_rtx (Pmode);
17753 tmp2 = gen_reg_rtx (Pmode);
17755 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17756 emit_move_insn (tmp1,
17757 gen_rtx_REG (Pmode, LR_REGNO));
17758 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17759 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17761 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17763 emit_insn (gen_load_toc_v4_pic_si ());
17764 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17766 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17769 rtx temp0 = (fromprolog
17770 ? gen_rtx_REG (Pmode, 0)
17771 : gen_reg_rtx (Pmode));
17777 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17778 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17780 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17781 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17783 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17784 emit_move_insn (dest,
17785 gen_rtx_REG (Pmode, LR_REGNO));
17786 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17792 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17793 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17794 emit_move_insn (dest,
17795 gen_rtx_REG (Pmode, LR_REGNO));
17796 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17798 emit_insn (gen_addsi3 (dest, temp0, dest));
17800 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17802 /* This is for AIX code running in non-PIC ELF32. */
17805 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17806 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17808 emit_insn (gen_elf_high (dest, realsym));
17809 emit_insn (gen_elf_low (dest, dest, realsym));
17813 gcc_assert (DEFAULT_ABI == ABI_AIX);
17816 emit_insn (gen_load_toc_aix_si (dest));
17818 emit_insn (gen_load_toc_aix_di (dest));
17822 /* Emit instructions to restore the link register after determining where
17823 its value has been stored. */
17826 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17828 rs6000_stack_t *info = rs6000_stack_info ();
17831 operands[0] = source;
17832 operands[1] = scratch;
17834 if (info->lr_save_p)
17836 rtx frame_rtx = stack_pointer_rtx;
17837 HOST_WIDE_INT sp_offset = 0;
17840 if (frame_pointer_needed
17841 || cfun->calls_alloca
17842 || info->total_size > 32767)
17844 tmp = gen_frame_mem (Pmode, frame_rtx);
17845 emit_move_insn (operands[1], tmp);
17846 frame_rtx = operands[1];
17848 else if (info->push_p)
17849 sp_offset = info->total_size;
17851 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17852 tmp = gen_frame_mem (Pmode, tmp);
17853 emit_move_insn (tmp, operands[0]);
17856 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17859 static GTY(()) alias_set_type set = -1;
17862 get_TOC_alias_set (void)
17865 set = new_alias_set ();
17869 /* This returns nonzero if the current function uses the TOC. This is
17870 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17871 is generated by the ABI_V4 load_toc_* patterns. */
17878 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17881 rtx pat = PATTERN (insn);
17884 if (GET_CODE (pat) == PARALLEL)
17885 for (i = 0; i < XVECLEN (pat, 0); i++)
17887 rtx sub = XVECEXP (pat, 0, i);
17888 if (GET_CODE (sub) == USE)
17890 sub = XEXP (sub, 0);
17891 if (GET_CODE (sub) == UNSPEC
17892 && XINT (sub, 1) == UNSPEC_TOC)
17902 create_TOC_reference (rtx symbol)
17904 if (TARGET_DEBUG_ADDR)
17906 if (GET_CODE (symbol) == SYMBOL_REF)
17907 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17911 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17912 GET_RTX_NAME (GET_CODE (symbol)));
17913 debug_rtx (symbol);
17917 if (!can_create_pseudo_p ())
17918 df_set_regs_ever_live (TOC_REGISTER, true);
17919 return gen_rtx_PLUS (Pmode,
17920 gen_rtx_REG (Pmode, TOC_REGISTER),
17921 gen_rtx_CONST (Pmode,
17922 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17925 /* Issue assembly directives that create a reference to the given DWARF
17926 FRAME_TABLE_LABEL from the current function section. */
17928 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17930 fprintf (asm_out_file, "\t.ref %s\n",
17931 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17934 /* If _Unwind_* has been called from within the same module,
17935 toc register is not guaranteed to be saved to 40(1) on function
17936 entry. Save it there in that case. */
17939 rs6000_aix_emit_builtin_unwind_init (void)
17942 rtx stack_top = gen_reg_rtx (Pmode);
17943 rtx opcode_addr = gen_reg_rtx (Pmode);
17944 rtx opcode = gen_reg_rtx (SImode);
17945 rtx tocompare = gen_reg_rtx (SImode);
17946 rtx no_toc_save_needed = gen_label_rtx ();
17948 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17949 emit_move_insn (stack_top, mem);
17951 mem = gen_frame_mem (Pmode,
17952 gen_rtx_PLUS (Pmode, stack_top,
17953 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17954 emit_move_insn (opcode_addr, mem);
17955 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17956 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17957 : 0xE8410028, SImode));
17959 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17960 SImode, NULL_RTX, NULL_RTX,
17961 no_toc_save_needed, -1);
17963 mem = gen_frame_mem (Pmode,
17964 gen_rtx_PLUS (Pmode, stack_top,
17965 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17966 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17967 emit_label (no_toc_save_needed);
17970 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17971 and the change to the stack pointer. */
17974 rs6000_emit_stack_tie (void)
17976 rtx mem = gen_frame_mem (BLKmode,
17977 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17979 emit_insn (gen_stack_tie (mem));
17982 /* Emit the correct code for allocating stack space, as insns.
17983 If COPY_R12, make sure a copy of the old frame is left in r12.
17984 If COPY_R11, make sure a copy of the old frame is left in r11,
17985 in preference to r12 if COPY_R12.
17986 The generated code may use hard register 0 as a temporary. */
17989 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17992 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17993 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17994 rtx todec = gen_int_mode (-size, Pmode);
17997 if (INTVAL (todec) != -size)
17999 warning (0, "stack frame too large");
18000 emit_insn (gen_trap ());
18004 if (crtl->limit_stack)
18006 if (REG_P (stack_limit_rtx)
18007 && REGNO (stack_limit_rtx) > 1
18008 && REGNO (stack_limit_rtx) <= 31)
18010 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18011 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18014 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18016 && DEFAULT_ABI == ABI_V4)
18018 rtx toload = gen_rtx_CONST (VOIDmode,
18019 gen_rtx_PLUS (Pmode,
18023 emit_insn (gen_elf_high (tmp_reg, toload));
18024 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18025 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18029 warning (0, "stack limit expression is not supported");
18032 if (copy_r12 || copy_r11)
18033 emit_move_insn (copy_r11
18034 ? gen_rtx_REG (Pmode, 11)
18035 : gen_rtx_REG (Pmode, 12),
18040 /* Need a note here so that try_split doesn't get confused. */
18041 if (get_last_insn () == NULL_RTX)
18042 emit_note (NOTE_INSN_DELETED);
18043 insn = emit_move_insn (tmp_reg, todec);
18044 try_split (PATTERN (insn), insn, 0);
18048 insn = emit_insn (TARGET_32BIT
18049 ? gen_movsi_update_stack (stack_reg, stack_reg,
18051 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18052 todec, stack_reg));
18053 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18054 it now and set the alias set/attributes. The above gen_*_update
18055 calls will generate a PARALLEL with the MEM set being the first
18057 par = PATTERN (insn);
18058 gcc_assert (GET_CODE (par) == PARALLEL);
18059 set = XVECEXP (par, 0, 0);
18060 gcc_assert (GET_CODE (set) == SET);
18061 mem = SET_DEST (set);
18062 gcc_assert (MEM_P (mem));
18063 MEM_NOTRAP_P (mem) = 1;
18064 set_mem_alias_set (mem, get_frame_alias_set ());
18066 RTX_FRAME_RELATED_P (insn) = 1;
18067 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18068 gen_rtx_SET (VOIDmode, stack_reg,
18069 gen_rtx_PLUS (Pmode, stack_reg,
18070 GEN_INT (-size))));
18073 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18074 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18075 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18076 deduce these equivalences by itself so it wasn't necessary to hold
18077 its hand so much. */
18080 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18081 rtx reg2, rtx rreg)
18085 /* copy_rtx will not make unique copies of registers, so we need to
18086 ensure we don't have unwanted sharing here. */
18088 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18091 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18093 real = copy_rtx (PATTERN (insn));
18095 if (reg2 != NULL_RTX)
18096 real = replace_rtx (real, reg2, rreg);
18098 real = replace_rtx (real, reg,
18099 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18100 STACK_POINTER_REGNUM),
18103 /* We expect that 'real' is either a SET or a PARALLEL containing
18104 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18105 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18107 if (GET_CODE (real) == SET)
18111 temp = simplify_rtx (SET_SRC (set));
18113 SET_SRC (set) = temp;
18114 temp = simplify_rtx (SET_DEST (set));
18116 SET_DEST (set) = temp;
18117 if (GET_CODE (SET_DEST (set)) == MEM)
18119 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18121 XEXP (SET_DEST (set), 0) = temp;
18128 gcc_assert (GET_CODE (real) == PARALLEL);
18129 for (i = 0; i < XVECLEN (real, 0); i++)
18130 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18132 rtx set = XVECEXP (real, 0, i);
18134 temp = simplify_rtx (SET_SRC (set));
18136 SET_SRC (set) = temp;
18137 temp = simplify_rtx (SET_DEST (set));
18139 SET_DEST (set) = temp;
18140 if (GET_CODE (SET_DEST (set)) == MEM)
18142 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18144 XEXP (SET_DEST (set), 0) = temp;
18146 RTX_FRAME_RELATED_P (set) = 1;
18150 RTX_FRAME_RELATED_P (insn) = 1;
18151 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18154 /* Returns an insn that has a vrsave set operation with the
18155 appropriate CLOBBERs. */
18158 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18161 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18162 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18165 = gen_rtx_SET (VOIDmode,
18167 gen_rtx_UNSPEC_VOLATILE (SImode,
18168 gen_rtvec (2, reg, vrsave),
18169 UNSPECV_SET_VRSAVE));
18173 /* We need to clobber the registers in the mask so the scheduler
18174 does not move sets to VRSAVE before sets of AltiVec registers.
18176 However, if the function receives nonlocal gotos, reload will set
18177 all call saved registers live. We will end up with:
18179 (set (reg 999) (mem))
18180 (parallel [ (set (reg vrsave) (unspec blah))
18181 (clobber (reg 999))])
18183 The clobber will cause the store into reg 999 to be dead, and
18184 flow will attempt to delete an epilogue insn. In this case, we
18185 need an unspec use/set of the register. */
18187 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18188 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18190 if (!epiloguep || call_used_regs [i])
18191 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18192 gen_rtx_REG (V4SImode, i));
18195 rtx reg = gen_rtx_REG (V4SImode, i);
18198 = gen_rtx_SET (VOIDmode,
18200 gen_rtx_UNSPEC (V4SImode,
18201 gen_rtvec (1, reg), 27));
18205 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18207 for (i = 0; i < nclobs; ++i)
18208 XVECEXP (insn, 0, i) = clobs[i];
18213 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18214 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18217 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18218 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18220 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18221 rtx replacea, replaceb;
18223 int_rtx = GEN_INT (offset);
18225 /* Some cases that need register indexed addressing. */
18226 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18227 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18228 || (TARGET_E500_DOUBLE && mode == DFmode)
18230 && SPE_VECTOR_MODE (mode)
18231 && !SPE_CONST_OFFSET_OK (offset)))
18233 /* Whomever calls us must make sure r11 is available in the
18234 flow path of instructions in the prologue. */
18235 offset_rtx = gen_rtx_REG (Pmode, 11);
18236 emit_move_insn (offset_rtx, int_rtx);
18238 replacea = offset_rtx;
18239 replaceb = int_rtx;
18243 offset_rtx = int_rtx;
18244 replacea = NULL_RTX;
18245 replaceb = NULL_RTX;
18248 reg = gen_rtx_REG (mode, regno);
18249 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18250 mem = gen_frame_mem (mode, addr);
18252 insn = emit_move_insn (mem, reg);
18254 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18257 /* Emit an offset memory reference suitable for a frame store, while
18258 converting to a valid addressing mode. */
18261 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18263 rtx int_rtx, offset_rtx;
18265 int_rtx = GEN_INT (offset);
18267 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18268 || (TARGET_E500_DOUBLE && mode == DFmode))
18270 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18271 emit_move_insn (offset_rtx, int_rtx);
18274 offset_rtx = int_rtx;
18276 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18279 /* Look for user-defined global regs. We should not save and restore these,
18280 and cannot use stmw/lmw if there are any in its range. */
18283 no_global_regs_above (int first, bool gpr)
18286 int last = gpr ? 32 : 64;
18287 for (i = first; i < last; i++)
18288 if (global_regs[i])
18293 #ifndef TARGET_FIX_AND_CONTINUE
18294 #define TARGET_FIX_AND_CONTINUE 0
18297 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18298 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18299 #define LAST_SAVRES_REGISTER 31
18300 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18302 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18304 /* Temporary holding space for an out-of-line register save/restore
18306 static char savres_routine_name[30];
18308 /* Return the name for an out-of-line register save/restore routine.
18309 We are saving/restoring GPRs if GPR is true. */
18312 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18313 bool savep, bool gpr, bool lr)
18315 const char *prefix = "";
18316 const char *suffix = "";
18318 /* Different targets are supposed to define
18319 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18320 routine name could be defined with:
18322 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18324 This is a nice idea in practice, but in reality, things are
18325 complicated in several ways:
18327 - ELF targets have save/restore routines for GPRs.
18329 - SPE targets use different prefixes for 32/64-bit registers, and
18330 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18332 - PPC64 ELF targets have routines for save/restore of GPRs that
18333 differ in what they do with the link register, so having a set
18334 prefix doesn't work. (We only use one of the save routines at
18335 the moment, though.)
18337 - PPC32 elf targets have "exit" versions of the restore routines
18338 that restore the link register and can save some extra space.
18339 These require an extra suffix. (There are also "tail" versions
18340 of the restore routines and "GOT" versions of the save routines,
18341 but we don't generate those at present. Same problems apply,
18344 We deal with all this by synthesizing our own prefix/suffix and
18345 using that for the simple sprintf call shown above. */
18348 /* No floating point saves on the SPE. */
18352 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18354 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18359 else if (DEFAULT_ABI == ABI_V4)
18365 prefix = savep ? "_savegpr_" : "_restgpr_";
18367 prefix = savep ? "_savefpr_" : "_restfpr_";
18372 else if (DEFAULT_ABI == ABI_AIX)
18374 #ifndef POWERPC_LINUX
18375 /* No out-of-line save/restore routines for GPRs on AIX. */
18376 gcc_assert (!TARGET_AIX || !gpr);
18382 ? (lr ? "_savegpr0_" : "_savegpr1_")
18383 : (lr ? "_restgpr0_" : "_restgpr1_"));
18384 #ifdef POWERPC_LINUX
18386 prefix = (savep ? "_savefpr_" : "_restfpr_");
18390 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18391 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18394 else if (DEFAULT_ABI == ABI_DARWIN)
18395 sorry ("Out-of-line save/restore routines not supported on Darwin");
18397 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18399 return savres_routine_name;
18402 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18403 We are saving/restoring GPRs if GPR is true. */
18406 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18409 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18411 int select = ((savep ? 1 : 0) << 2
18413 /* On the SPE, we never have any FPRs, but we do have
18414 32/64-bit versions of the routines. */
18415 ? (info->spe_64bit_regs_used ? 1 : 0)
18416 : (gpr ? 1 : 0)) << 1)
18419 /* Don't generate bogus routine names. */
18420 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18421 && regno <= LAST_SAVRES_REGISTER);
18423 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18429 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18431 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18432 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18433 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18439 /* Emit a sequence of insns, including a stack tie if needed, for
18440 resetting the stack pointer. If SAVRES is true, then don't reset the
18441 stack pointer, but move the base of the frame into r11 for use by
18442 out-of-line register restore routines. */
18445 rs6000_emit_stack_reset (rs6000_stack_t *info,
18446 rtx sp_reg_rtx, rtx frame_reg_rtx,
18447 int sp_offset, bool savres)
18449 /* This blockage is needed so that sched doesn't decide to move
18450 the sp change before the register restores. */
18451 if (frame_reg_rtx != sp_reg_rtx
18453 && info->spe_64bit_regs_used != 0
18454 && info->first_gp_reg_save != 32))
18455 rs6000_emit_stack_tie ();
18457 if (frame_reg_rtx != sp_reg_rtx)
18459 if (sp_offset != 0)
18461 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18462 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18463 GEN_INT (sp_offset)));
18466 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18468 else if (sp_offset != 0)
18470 /* If we are restoring registers out-of-line, we will be using the
18471 "exit" variants of the restore routines, which will reset the
18472 stack for us. But we do need to point r11 into the right place
18473 for those routines. */
18474 rtx dest_reg = (savres
18475 ? gen_rtx_REG (Pmode, 11)
18478 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18479 GEN_INT (sp_offset)));
18486 /* Construct a parallel rtx describing the effect of a call to an
18487 out-of-line register save/restore routine. */
18490 rs6000_make_savres_rtx (rs6000_stack_t *info,
18491 rtx frame_reg_rtx, int save_area_offset,
18492 enum machine_mode reg_mode,
18493 bool savep, bool gpr, bool lr)
18496 int offset, start_reg, end_reg, n_regs;
18497 int reg_size = GET_MODE_SIZE (reg_mode);
18503 ? info->first_gp_reg_save
18504 : info->first_fp_reg_save);
18505 end_reg = gpr ? 32 : 64;
18506 n_regs = end_reg - start_reg;
18507 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18510 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18512 RTVEC_ELT (p, offset++)
18513 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18515 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18516 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18517 RTVEC_ELT (p, offset++)
18518 = gen_rtx_USE (VOIDmode,
18519 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18523 for (i = 0; i < end_reg - start_reg; i++)
18525 rtx addr, reg, mem;
18526 reg = gen_rtx_REG (reg_mode, start_reg + i);
18527 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18528 GEN_INT (save_area_offset + reg_size*i));
18529 mem = gen_frame_mem (reg_mode, addr);
18531 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18533 savep ? reg : mem);
18538 rtx addr, reg, mem;
18539 reg = gen_rtx_REG (Pmode, 0);
18540 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18541 GEN_INT (info->lr_save_offset));
18542 mem = gen_frame_mem (Pmode, addr);
18543 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18546 return gen_rtx_PARALLEL (VOIDmode, p);
18549 /* Determine whether the gp REG is really used. */
18552 rs6000_reg_live_or_pic_offset_p (int reg)
18554 return ((df_regs_ever_live_p (reg)
18555 && (!call_used_regs[reg]
18556 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18557 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18558 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18559 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18560 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18564 SAVRES_MULTIPLE = 0x1,
18565 SAVRES_INLINE_FPRS = 0x2,
18566 SAVRES_INLINE_GPRS = 0x4,
18567 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18568 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18569 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18572 /* Determine the strategy for savings/restoring registers. */
18575 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18576 int using_static_chain_p, int sibcall)
18578 bool using_multiple_p;
18580 bool savres_fprs_inline;
18581 bool savres_gprs_inline;
18582 bool noclobber_global_gprs
18583 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18586 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18587 && (!TARGET_SPE_ABI
18588 || info->spe_64bit_regs_used == 0)
18589 && info->first_gp_reg_save < 31
18590 && noclobber_global_gprs);
18591 /* Don't bother to try to save things out-of-line if r11 is occupied
18592 by the static chain. It would require too much fiddling and the
18593 static chain is rarely used anyway. */
18594 common = (using_static_chain_p
18596 || crtl->calls_eh_return
18597 || !info->lr_save_p
18598 || cfun->machine->ra_need_lr
18599 || info->total_size > 32767);
18600 savres_fprs_inline = (common
18601 || info->first_fp_reg_save == 64
18602 || !no_global_regs_above (info->first_fp_reg_save,
18604 /* The out-of-line FP routines use
18605 double-precision stores; we can't use those
18606 routines if we don't have such stores. */
18607 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18608 || FP_SAVE_INLINE (info->first_fp_reg_save));
18609 savres_gprs_inline = (common
18610 /* Saving CR interferes with the exit routines
18611 used on the SPE, so just punt here. */
18614 && info->spe_64bit_regs_used != 0
18615 && info->cr_save_p != 0)
18616 || info->first_gp_reg_save == 32
18617 || !noclobber_global_gprs
18618 || GP_SAVE_INLINE (info->first_gp_reg_save));
18621 /* If we are going to use store multiple, then don't even bother
18622 with the out-of-line routines, since the store-multiple instruction
18623 will always be smaller. */
18624 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18627 /* The situation is more complicated with load multiple. We'd
18628 prefer to use the out-of-line routines for restores, since the
18629 "exit" out-of-line routines can handle the restore of LR and
18630 the frame teardown. But we can only use the out-of-line
18631 routines if we know that we've used store multiple or
18632 out-of-line routines in the prologue, i.e. if we've saved all
18633 the registers from first_gp_reg_save. Otherwise, we risk
18634 loading garbage from the stack. Furthermore, we can only use
18635 the "exit" out-of-line gpr restore if we haven't saved any
18637 bool saved_all = !savres_gprs_inline || using_multiple_p;
18639 if (saved_all && info->first_fp_reg_save != 64)
18640 /* We can't use the exit routine; use load multiple if it's
18642 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18645 strategy = (using_multiple_p
18646 | (savres_fprs_inline << 1)
18647 | (savres_gprs_inline << 2));
18648 #ifdef POWERPC_LINUX
18651 if (!savres_fprs_inline)
18652 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18653 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18654 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18657 if (TARGET_AIX && !savres_fprs_inline)
18658 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18663 /* Emit function prologue as insns. */
18666 rs6000_emit_prologue (void)
18668 rs6000_stack_t *info = rs6000_stack_info ();
18669 enum machine_mode reg_mode = Pmode;
18670 int reg_size = TARGET_32BIT ? 4 : 8;
18671 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18672 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18673 rtx frame_reg_rtx = sp_reg_rtx;
18674 rtx cr_save_rtx = NULL_RTX;
18677 int saving_FPRs_inline;
18678 int saving_GPRs_inline;
18679 int using_store_multiple;
18680 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18681 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18682 && call_used_regs[STATIC_CHAIN_REGNUM]);
18683 HOST_WIDE_INT sp_offset = 0;
18685 if (TARGET_FIX_AND_CONTINUE)
18687 /* gdb on darwin arranges to forward a function from the old
18688 address by modifying the first 5 instructions of the function
18689 to branch to the overriding function. This is necessary to
18690 permit function pointers that point to the old function to
18691 actually forward to the new function. */
18692 emit_insn (gen_nop ());
18693 emit_insn (gen_nop ());
18694 emit_insn (gen_nop ());
18695 emit_insn (gen_nop ());
18696 emit_insn (gen_nop ());
18699 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18701 reg_mode = V2SImode;
18705 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18706 /*static_chain_p=*/using_static_chain_p,
18708 using_store_multiple = strategy & SAVRES_MULTIPLE;
18709 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18710 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18712 /* For V.4, update stack before we do any saving and set back pointer. */
18713 if (! WORLD_SAVE_P (info)
18715 && (DEFAULT_ABI == ABI_V4
18716 || crtl->calls_eh_return))
18718 bool need_r11 = (TARGET_SPE
18719 ? (!saving_GPRs_inline
18720 && info->spe_64bit_regs_used == 0)
18721 : (!saving_FPRs_inline || !saving_GPRs_inline));
18722 if (info->total_size < 32767)
18723 sp_offset = info->total_size;
18725 frame_reg_rtx = (need_r11
18726 ? gen_rtx_REG (Pmode, 11)
18728 rs6000_emit_allocate_stack (info->total_size,
18729 (frame_reg_rtx != sp_reg_rtx
18730 && (info->cr_save_p
18732 || info->first_fp_reg_save < 64
18733 || info->first_gp_reg_save < 32
18736 if (frame_reg_rtx != sp_reg_rtx)
18737 rs6000_emit_stack_tie ();
18740 /* Handle world saves specially here. */
18741 if (WORLD_SAVE_P (info))
18748 /* save_world expects lr in r0. */
18749 reg0 = gen_rtx_REG (Pmode, 0);
18750 if (info->lr_save_p)
18752 insn = emit_move_insn (reg0,
18753 gen_rtx_REG (Pmode, LR_REGNO));
18754 RTX_FRAME_RELATED_P (insn) = 1;
18757 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18758 assumptions about the offsets of various bits of the stack
18760 gcc_assert (info->gp_save_offset == -220
18761 && info->fp_save_offset == -144
18762 && info->lr_save_offset == 8
18763 && info->cr_save_offset == 4
18766 && (!crtl->calls_eh_return
18767 || info->ehrd_offset == -432)
18768 && info->vrsave_save_offset == -224
18769 && info->altivec_save_offset == -416);
18771 treg = gen_rtx_REG (SImode, 11);
18772 emit_move_insn (treg, GEN_INT (-info->total_size));
18774 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18775 in R11. It also clobbers R12, so beware! */
18777 /* Preserve CR2 for save_world prologues */
18779 sz += 32 - info->first_gp_reg_save;
18780 sz += 64 - info->first_fp_reg_save;
18781 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18782 p = rtvec_alloc (sz);
18784 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18785 gen_rtx_REG (SImode,
18787 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18788 gen_rtx_SYMBOL_REF (Pmode,
18790 /* We do floats first so that the instruction pattern matches
18792 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18794 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18795 ? DFmode : SFmode),
18796 info->first_fp_reg_save + i);
18797 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18798 GEN_INT (info->fp_save_offset
18799 + sp_offset + 8 * i));
18800 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18801 ? DFmode : SFmode), addr);
18803 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18805 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18807 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18808 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18809 GEN_INT (info->altivec_save_offset
18810 + sp_offset + 16 * i));
18811 rtx mem = gen_frame_mem (V4SImode, addr);
18813 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18815 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18817 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18818 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18819 GEN_INT (info->gp_save_offset
18820 + sp_offset + reg_size * i));
18821 rtx mem = gen_frame_mem (reg_mode, addr);
18823 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18827 /* CR register traditionally saved as CR2. */
18828 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18829 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18830 GEN_INT (info->cr_save_offset
18832 rtx mem = gen_frame_mem (reg_mode, addr);
18834 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18836 /* Explain about use of R0. */
18837 if (info->lr_save_p)
18839 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18840 GEN_INT (info->lr_save_offset
18842 rtx mem = gen_frame_mem (reg_mode, addr);
18844 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18846 /* Explain what happens to the stack pointer. */
18848 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18849 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18852 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18853 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18854 treg, GEN_INT (-info->total_size));
18855 sp_offset = info->total_size;
18858 /* If we use the link register, get it into r0. */
18859 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18861 rtx addr, reg, mem;
18863 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18864 gen_rtx_REG (Pmode, LR_REGNO));
18865 RTX_FRAME_RELATED_P (insn) = 1;
18867 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18868 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18870 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18871 GEN_INT (info->lr_save_offset + sp_offset));
18872 reg = gen_rtx_REG (Pmode, 0);
18873 mem = gen_rtx_MEM (Pmode, addr);
18874 /* This should not be of rs6000_sr_alias_set, because of
18875 __builtin_return_address. */
18877 insn = emit_move_insn (mem, reg);
18878 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18879 NULL_RTX, NULL_RTX);
18883 /* If we need to save CR, put it into r12 or r11. */
18884 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18889 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18891 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18892 RTX_FRAME_RELATED_P (insn) = 1;
18893 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18894 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18895 But that's OK. All we have to do is specify that _one_ condition
18896 code register is saved in this stack slot. The thrower's epilogue
18897 will then restore all the call-saved registers.
18898 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18899 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18900 gen_rtx_REG (SImode, CR2_REGNO));
18901 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18904 /* Do any required saving of fpr's. If only one or two to save, do
18905 it ourselves. Otherwise, call function. */
18906 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18909 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18910 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18911 && ! call_used_regs[info->first_fp_reg_save+i]))
18912 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18913 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18915 info->first_fp_reg_save + i,
18916 info->fp_save_offset + sp_offset + 8 * i,
18919 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18923 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18924 info->fp_save_offset + sp_offset,
18926 /*savep=*/true, /*gpr=*/false,
18928 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18930 insn = emit_insn (par);
18931 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18932 NULL_RTX, NULL_RTX);
18935 /* Save GPRs. This is done as a PARALLEL if we are using
18936 the store-multiple instructions. */
18937 if (!WORLD_SAVE_P (info)
18939 && info->spe_64bit_regs_used != 0
18940 && info->first_gp_reg_save != 32)
18943 rtx spe_save_area_ptr;
18945 /* Determine whether we can address all of the registers that need
18946 to be saved with an offset from the stack pointer that fits in
18947 the small const field for SPE memory instructions. */
18948 int spe_regs_addressable_via_sp
18949 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18950 + (32 - info->first_gp_reg_save - 1) * reg_size)
18951 && saving_GPRs_inline);
18954 if (spe_regs_addressable_via_sp)
18956 spe_save_area_ptr = frame_reg_rtx;
18957 spe_offset = info->spe_gp_save_offset + sp_offset;
18961 /* Make r11 point to the start of the SPE save area. We need
18962 to be careful here if r11 is holding the static chain. If
18963 it is, then temporarily save it in r0. We would use r0 as
18964 our base register here, but using r0 as a base register in
18965 loads and stores means something different from what we
18967 int ool_adjust = (saving_GPRs_inline
18969 : (info->first_gp_reg_save
18970 - (FIRST_SAVRES_REGISTER+1))*8);
18971 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18972 + sp_offset - ool_adjust);
18974 if (using_static_chain_p)
18976 rtx r0 = gen_rtx_REG (Pmode, 0);
18977 gcc_assert (info->first_gp_reg_save > 11);
18979 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18982 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18983 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18985 GEN_INT (offset)));
18986 /* We need to make sure the move to r11 gets noted for
18987 properly outputting unwind information. */
18988 if (!saving_GPRs_inline)
18989 rs6000_frame_related (insn, frame_reg_rtx, offset,
18990 NULL_RTX, NULL_RTX);
18994 if (saving_GPRs_inline)
18996 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18997 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18999 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19000 rtx offset, addr, mem;
19002 /* We're doing all this to ensure that the offset fits into
19003 the immediate offset of 'evstdd'. */
19004 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19006 offset = GEN_INT (reg_size * i + spe_offset);
19007 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19008 mem = gen_rtx_MEM (V2SImode, addr);
19010 insn = emit_move_insn (mem, reg);
19012 rs6000_frame_related (insn, spe_save_area_ptr,
19013 info->spe_gp_save_offset
19014 + sp_offset + reg_size * i,
19015 offset, const0_rtx);
19022 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19024 /*savep=*/true, /*gpr=*/true,
19026 insn = emit_insn (par);
19027 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19028 NULL_RTX, NULL_RTX);
19032 /* Move the static chain pointer back. */
19033 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19034 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19036 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19040 /* Need to adjust r11 (r12) if we saved any FPRs. */
19041 if (info->first_fp_reg_save != 64)
19043 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19045 rtx offset = GEN_INT (sp_offset
19046 + (-8 * (64-info->first_fp_reg_save)));
19047 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19050 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19051 info->gp_save_offset + sp_offset,
19053 /*savep=*/true, /*gpr=*/true,
19055 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19057 insn = emit_insn (par);
19058 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19059 NULL_RTX, NULL_RTX);
19061 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19065 p = rtvec_alloc (32 - info->first_gp_reg_save);
19066 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19068 rtx addr, reg, mem;
19069 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19070 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19071 GEN_INT (info->gp_save_offset
19074 mem = gen_frame_mem (reg_mode, addr);
19076 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19078 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19079 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19080 NULL_RTX, NULL_RTX);
19082 else if (!WORLD_SAVE_P (info))
19085 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19086 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19088 rtx addr, reg, mem;
19089 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19091 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19092 GEN_INT (info->gp_save_offset
19095 mem = gen_frame_mem (reg_mode, addr);
19097 insn = emit_move_insn (mem, reg);
19098 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19099 NULL_RTX, NULL_RTX);
19103 /* ??? There's no need to emit actual instructions here, but it's the
19104 easiest way to get the frame unwind information emitted. */
19105 if (crtl->calls_eh_return)
19107 unsigned int i, regno;
19109 /* In AIX ABI we need to pretend we save r2 here. */
19112 rtx addr, reg, mem;
19114 reg = gen_rtx_REG (reg_mode, 2);
19115 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19116 GEN_INT (sp_offset + 5 * reg_size));
19117 mem = gen_frame_mem (reg_mode, addr);
19119 insn = emit_move_insn (mem, reg);
19120 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19121 NULL_RTX, NULL_RTX);
19122 PATTERN (insn) = gen_blockage ();
19127 regno = EH_RETURN_DATA_REGNO (i);
19128 if (regno == INVALID_REGNUM)
19131 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19132 info->ehrd_offset + sp_offset
19133 + reg_size * (int) i,
19138 /* Save CR if we use any that must be preserved. */
19139 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19141 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19142 GEN_INT (info->cr_save_offset + sp_offset));
19143 rtx mem = gen_frame_mem (SImode, addr);
19144 /* See the large comment above about why CR2_REGNO is used. */
19145 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19147 /* If r12 was used to hold the original sp, copy cr into r0 now
19149 if (REGNO (frame_reg_rtx) == 12)
19153 cr_save_rtx = gen_rtx_REG (SImode, 0);
19154 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19155 RTX_FRAME_RELATED_P (insn) = 1;
19156 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19157 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19159 insn = emit_move_insn (mem, cr_save_rtx);
19161 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19162 NULL_RTX, NULL_RTX);
19165 /* Update stack and set back pointer unless this is V.4,
19166 for which it was done previously. */
19167 if (!WORLD_SAVE_P (info) && info->push_p
19168 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19170 if (info->total_size < 32767)
19171 sp_offset = info->total_size;
19173 frame_reg_rtx = frame_ptr_rtx;
19174 rs6000_emit_allocate_stack (info->total_size,
19175 (frame_reg_rtx != sp_reg_rtx
19176 && ((info->altivec_size != 0)
19177 || (info->vrsave_mask != 0)
19180 if (frame_reg_rtx != sp_reg_rtx)
19181 rs6000_emit_stack_tie ();
19184 /* Set frame pointer, if needed. */
19185 if (frame_pointer_needed)
19187 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19189 RTX_FRAME_RELATED_P (insn) = 1;
19192 /* Save AltiVec registers if needed. Save here because the red zone does
19193 not include AltiVec registers. */
19194 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19198 /* There should be a non inline version of this, for when we
19199 are saving lots of vector registers. */
19200 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19201 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19203 rtx areg, savereg, mem;
19206 offset = info->altivec_save_offset + sp_offset
19207 + 16 * (i - info->first_altivec_reg_save);
19209 savereg = gen_rtx_REG (V4SImode, i);
19211 areg = gen_rtx_REG (Pmode, 0);
19212 emit_move_insn (areg, GEN_INT (offset));
19214 /* AltiVec addressing mode is [reg+reg]. */
19215 mem = gen_frame_mem (V4SImode,
19216 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19218 insn = emit_move_insn (mem, savereg);
19220 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19221 areg, GEN_INT (offset));
19225 /* VRSAVE is a bit vector representing which AltiVec registers
19226 are used. The OS uses this to determine which vector
19227 registers to save on a context switch. We need to save
19228 VRSAVE on the stack frame, add whatever AltiVec registers we
19229 used in this function, and do the corresponding magic in the
19232 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19233 && info->vrsave_mask != 0)
19235 rtx reg, mem, vrsave;
19238 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19239 as frame_reg_rtx and r11 as the static chain pointer for
19240 nested functions. */
19241 reg = gen_rtx_REG (SImode, 0);
19242 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19244 emit_insn (gen_get_vrsave_internal (reg));
19246 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19248 if (!WORLD_SAVE_P (info))
19251 offset = info->vrsave_save_offset + sp_offset;
19252 mem = gen_frame_mem (SImode,
19253 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19254 GEN_INT (offset)));
19255 insn = emit_move_insn (mem, reg);
19258 /* Include the registers in the mask. */
19259 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19261 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19264 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19265 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19266 || (DEFAULT_ABI == ABI_V4
19267 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19268 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19270 /* If emit_load_toc_table will use the link register, we need to save
19271 it. We use R12 for this purpose because emit_load_toc_table
19272 can use register 0. This allows us to use a plain 'blr' to return
19273 from the procedure more often. */
19274 int save_LR_around_toc_setup = (TARGET_ELF
19275 && DEFAULT_ABI != ABI_AIX
19277 && ! info->lr_save_p
19278 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19279 if (save_LR_around_toc_setup)
19281 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19283 insn = emit_move_insn (frame_ptr_rtx, lr);
19284 RTX_FRAME_RELATED_P (insn) = 1;
19286 rs6000_emit_load_toc_table (TRUE);
19288 insn = emit_move_insn (lr, frame_ptr_rtx);
19289 RTX_FRAME_RELATED_P (insn) = 1;
19292 rs6000_emit_load_toc_table (TRUE);
19296 if (DEFAULT_ABI == ABI_DARWIN
19297 && flag_pic && crtl->uses_pic_offset_table)
19299 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19300 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19302 /* Save and restore LR locally around this call (in R0). */
19303 if (!info->lr_save_p)
19304 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19306 emit_insn (gen_load_macho_picbase (src));
19308 emit_move_insn (gen_rtx_REG (Pmode,
19309 RS6000_PIC_OFFSET_TABLE_REGNUM),
19312 if (!info->lr_save_p)
19313 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19318 /* Write function prologue. */
19321 rs6000_output_function_prologue (FILE *file,
19322 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19324 rs6000_stack_t *info = rs6000_stack_info ();
19326 if (TARGET_DEBUG_STACK)
19327 debug_stack_info (info);
19329 /* Write .extern for any function we will call to save and restore
19331 if (info->first_fp_reg_save < 64
19332 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19335 int regno = info->first_fp_reg_save - 32;
19337 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19338 /*gpr=*/false, /*lr=*/false);
19339 fprintf (file, "\t.extern %s\n", name);
19341 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19342 /*gpr=*/false, /*lr=*/true);
19343 fprintf (file, "\t.extern %s\n", name);
19346 /* Write .extern for AIX common mode routines, if needed. */
19347 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19349 fputs ("\t.extern __mulh\n", file);
19350 fputs ("\t.extern __mull\n", file);
19351 fputs ("\t.extern __divss\n", file);
19352 fputs ("\t.extern __divus\n", file);
19353 fputs ("\t.extern __quoss\n", file);
19354 fputs ("\t.extern __quous\n", file);
19355 common_mode_defined = 1;
19358 if (! HAVE_prologue)
19364 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19365 the "toplevel" insn chain. */
19366 emit_note (NOTE_INSN_DELETED);
19367 rs6000_emit_prologue ();
19368 emit_note (NOTE_INSN_DELETED);
19370 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19374 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19376 INSN_ADDRESSES_NEW (insn, addr);
19381 prologue = get_insns ();
19384 if (TARGET_DEBUG_STACK)
19385 debug_rtx_list (prologue, 100);
19387 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19391 rs6000_pic_labelno++;
19394 /* Non-zero if vmx regs are restored before the frame pop, zero if
19395 we restore after the pop when possible. */
19396 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19398 /* Reload CR from REG. */
19401 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19406 if (using_mfcr_multiple)
19408 for (i = 0; i < 8; i++)
19409 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19411 gcc_assert (count);
19414 if (using_mfcr_multiple && count > 1)
19419 p = rtvec_alloc (count);
19422 for (i = 0; i < 8; i++)
19423 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19425 rtvec r = rtvec_alloc (2);
19426 RTVEC_ELT (r, 0) = reg;
19427 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19428 RTVEC_ELT (p, ndx) =
19429 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19430 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19433 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19434 gcc_assert (ndx == count);
19437 for (i = 0; i < 8; i++)
19438 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19440 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19446 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19447 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19448 below stack pointer not cloberred by signals. */
19451 offset_below_red_zone_p (HOST_WIDE_INT offset)
19453 return offset < (DEFAULT_ABI == ABI_V4
19455 : TARGET_32BIT ? -220 : -288);
19458 /* Emit function epilogue as insns. */
19461 rs6000_emit_epilogue (int sibcall)
19463 rs6000_stack_t *info;
19464 int restoring_GPRs_inline;
19465 int restoring_FPRs_inline;
19466 int using_load_multiple;
19467 int using_mtcr_multiple;
19468 int use_backchain_to_restore_sp;
19472 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19473 rtx frame_reg_rtx = sp_reg_rtx;
19474 rtx cfa_restores = NULL_RTX;
19476 rtx cr_save_reg = NULL_RTX;
19477 enum machine_mode reg_mode = Pmode;
19478 int reg_size = TARGET_32BIT ? 4 : 8;
19481 info = rs6000_stack_info ();
19483 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19485 reg_mode = V2SImode;
19489 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19490 /*static_chain_p=*/0, sibcall);
19491 using_load_multiple = strategy & SAVRES_MULTIPLE;
19492 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19493 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19494 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19495 || rs6000_cpu == PROCESSOR_PPC603
19496 || rs6000_cpu == PROCESSOR_PPC750
19498 /* Restore via the backchain when we have a large frame, since this
19499 is more efficient than an addis, addi pair. The second condition
19500 here will not trigger at the moment; We don't actually need a
19501 frame pointer for alloca, but the generic parts of the compiler
19502 give us one anyway. */
19503 use_backchain_to_restore_sp = (info->total_size > 32767
19504 || info->total_size
19505 + (info->lr_save_p ? info->lr_save_offset : 0)
19507 || (cfun->calls_alloca
19508 && !frame_pointer_needed));
19509 restore_lr = (info->lr_save_p
19510 && (restoring_FPRs_inline
19511 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19512 && (restoring_GPRs_inline
19513 || info->first_fp_reg_save < 64));
19515 if (WORLD_SAVE_P (info))
19519 const char *alloc_rname;
19522 /* eh_rest_world_r10 will return to the location saved in the LR
19523 stack slot (which is not likely to be our caller.)
19524 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19525 rest_world is similar, except any R10 parameter is ignored.
19526 The exception-handling stuff that was here in 2.95 is no
19527 longer necessary. */
19531 + 32 - info->first_gp_reg_save
19532 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19533 + 63 + 1 - info->first_fp_reg_save);
19535 strcpy (rname, ((crtl->calls_eh_return) ?
19536 "*eh_rest_world_r10" : "*rest_world"));
19537 alloc_rname = ggc_strdup (rname);
19540 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19541 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19542 gen_rtx_REG (Pmode,
19545 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19546 /* The instruction pattern requires a clobber here;
19547 it is shared with the restVEC helper. */
19549 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19552 /* CR register traditionally saved as CR2. */
19553 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19554 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19555 GEN_INT (info->cr_save_offset));
19556 rtx mem = gen_frame_mem (reg_mode, addr);
19558 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19561 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19563 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19564 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19565 GEN_INT (info->gp_save_offset
19567 rtx mem = gen_frame_mem (reg_mode, addr);
19569 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19571 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19573 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19574 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19575 GEN_INT (info->altivec_save_offset
19577 rtx mem = gen_frame_mem (V4SImode, addr);
19579 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19581 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19583 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19584 ? DFmode : SFmode),
19585 info->first_fp_reg_save + i);
19586 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19587 GEN_INT (info->fp_save_offset
19589 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19590 ? DFmode : SFmode), addr);
19592 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19595 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19597 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19599 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19601 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19603 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19604 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19609 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19611 sp_offset = info->total_size;
19613 /* Restore AltiVec registers if we must do so before adjusting the
19615 if (TARGET_ALTIVEC_ABI
19616 && info->altivec_size != 0
19617 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19618 || (DEFAULT_ABI != ABI_V4
19619 && offset_below_red_zone_p (info->altivec_save_offset))))
19623 if (use_backchain_to_restore_sp)
19625 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19626 emit_move_insn (frame_reg_rtx,
19627 gen_rtx_MEM (Pmode, sp_reg_rtx));
19630 else if (frame_pointer_needed)
19631 frame_reg_rtx = hard_frame_pointer_rtx;
19633 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19634 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19636 rtx addr, areg, mem, reg;
19638 areg = gen_rtx_REG (Pmode, 0);
19640 (areg, GEN_INT (info->altivec_save_offset
19642 + 16 * (i - info->first_altivec_reg_save)));
19644 /* AltiVec addressing mode is [reg+reg]. */
19645 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19646 mem = gen_frame_mem (V4SImode, addr);
19648 reg = gen_rtx_REG (V4SImode, i);
19649 emit_move_insn (reg, mem);
19650 if (offset_below_red_zone_p (info->altivec_save_offset
19651 + (i - info->first_altivec_reg_save)
19653 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19658 /* Restore VRSAVE if we must do so before adjusting the stack. */
19660 && TARGET_ALTIVEC_VRSAVE
19661 && info->vrsave_mask != 0
19662 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19663 || (DEFAULT_ABI != ABI_V4
19664 && offset_below_red_zone_p (info->vrsave_save_offset))))
19666 rtx addr, mem, reg;
19668 if (frame_reg_rtx == sp_reg_rtx)
19670 if (use_backchain_to_restore_sp)
19672 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19673 emit_move_insn (frame_reg_rtx,
19674 gen_rtx_MEM (Pmode, sp_reg_rtx));
19677 else if (frame_pointer_needed)
19678 frame_reg_rtx = hard_frame_pointer_rtx;
19681 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19682 GEN_INT (info->vrsave_save_offset + sp_offset));
19683 mem = gen_frame_mem (SImode, addr);
19684 reg = gen_rtx_REG (SImode, 12);
19685 emit_move_insn (reg, mem);
19687 emit_insn (generate_set_vrsave (reg, info, 1));
19691 /* If we have a large stack frame, restore the old stack pointer
19692 using the backchain. */
19693 if (use_backchain_to_restore_sp)
19695 if (frame_reg_rtx == sp_reg_rtx)
19697 /* Under V.4, don't reset the stack pointer until after we're done
19698 loading the saved registers. */
19699 if (DEFAULT_ABI == ABI_V4)
19700 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19702 insn = emit_move_insn (frame_reg_rtx,
19703 gen_rtx_MEM (Pmode, sp_reg_rtx));
19706 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19707 && DEFAULT_ABI == ABI_V4)
19708 /* frame_reg_rtx has been set up by the altivec restore. */
19712 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19713 frame_reg_rtx = sp_reg_rtx;
19716 /* If we have a frame pointer, we can restore the old stack pointer
19718 else if (frame_pointer_needed)
19720 frame_reg_rtx = sp_reg_rtx;
19721 if (DEFAULT_ABI == ABI_V4)
19722 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19724 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19725 GEN_INT (info->total_size)));
19728 else if (info->push_p
19729 && DEFAULT_ABI != ABI_V4
19730 && !crtl->calls_eh_return)
19732 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19733 GEN_INT (info->total_size)));
19736 if (insn && frame_reg_rtx == sp_reg_rtx)
19740 REG_NOTES (insn) = cfa_restores;
19741 cfa_restores = NULL_RTX;
19743 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19744 RTX_FRAME_RELATED_P (insn) = 1;
19747 /* Restore AltiVec registers if we have not done so already. */
19748 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19749 && TARGET_ALTIVEC_ABI
19750 && info->altivec_size != 0
19751 && (DEFAULT_ABI == ABI_V4
19752 || !offset_below_red_zone_p (info->altivec_save_offset)))
19756 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19757 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19759 rtx addr, areg, mem, reg;
19761 areg = gen_rtx_REG (Pmode, 0);
19763 (areg, GEN_INT (info->altivec_save_offset
19765 + 16 * (i - info->first_altivec_reg_save)));
19767 /* AltiVec addressing mode is [reg+reg]. */
19768 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19769 mem = gen_frame_mem (V4SImode, addr);
19771 reg = gen_rtx_REG (V4SImode, i);
19772 emit_move_insn (reg, mem);
19773 if (DEFAULT_ABI == ABI_V4)
19774 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19779 /* Restore VRSAVE if we have not done so already. */
19780 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19782 && TARGET_ALTIVEC_VRSAVE
19783 && info->vrsave_mask != 0
19784 && (DEFAULT_ABI == ABI_V4
19785 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19787 rtx addr, mem, reg;
19789 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19790 GEN_INT (info->vrsave_save_offset + sp_offset));
19791 mem = gen_frame_mem (SImode, addr);
19792 reg = gen_rtx_REG (SImode, 12);
19793 emit_move_insn (reg, mem);
19795 emit_insn (generate_set_vrsave (reg, info, 1));
19798 /* Get the old lr if we saved it. If we are restoring registers
19799 out-of-line, then the out-of-line routines can do this for us. */
19800 if (restore_lr && restoring_GPRs_inline)
19802 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19803 info->lr_save_offset + sp_offset);
19805 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19808 /* Get the old cr if we saved it. */
19809 if (info->cr_save_p)
19811 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19812 GEN_INT (info->cr_save_offset + sp_offset));
19813 rtx mem = gen_frame_mem (SImode, addr);
19815 cr_save_reg = gen_rtx_REG (SImode,
19816 DEFAULT_ABI == ABI_AIX
19817 && !restoring_GPRs_inline
19818 && info->first_fp_reg_save < 64
19820 emit_move_insn (cr_save_reg, mem);
19823 /* Set LR here to try to overlap restores below. LR is always saved
19824 above incoming stack, so it never needs REG_CFA_RESTORE. */
19825 if (restore_lr && restoring_GPRs_inline)
19826 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19827 gen_rtx_REG (Pmode, 0));
19829 /* Load exception handler data registers, if needed. */
19830 if (crtl->calls_eh_return)
19832 unsigned int i, regno;
19836 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19837 GEN_INT (sp_offset + 5 * reg_size));
19838 rtx mem = gen_frame_mem (reg_mode, addr);
19840 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19847 regno = EH_RETURN_DATA_REGNO (i);
19848 if (regno == INVALID_REGNUM)
19851 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19852 info->ehrd_offset + sp_offset
19853 + reg_size * (int) i);
19855 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19859 /* Restore GPRs. This is done as a PARALLEL if we are using
19860 the load-multiple instructions. */
19862 && info->spe_64bit_regs_used != 0
19863 && info->first_gp_reg_save != 32)
19865 /* Determine whether we can address all of the registers that need
19866 to be saved with an offset from the stack pointer that fits in
19867 the small const field for SPE memory instructions. */
19868 int spe_regs_addressable_via_sp
19869 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19870 + (32 - info->first_gp_reg_save - 1) * reg_size)
19871 && restoring_GPRs_inline);
19874 if (spe_regs_addressable_via_sp)
19875 spe_offset = info->spe_gp_save_offset + sp_offset;
19878 rtx old_frame_reg_rtx = frame_reg_rtx;
19879 /* Make r11 point to the start of the SPE save area. We worried about
19880 not clobbering it when we were saving registers in the prologue.
19881 There's no need to worry here because the static chain is passed
19882 anew to every function. */
19883 int ool_adjust = (restoring_GPRs_inline
19885 : (info->first_gp_reg_save
19886 - (FIRST_SAVRES_REGISTER+1))*8);
19888 if (frame_reg_rtx == sp_reg_rtx)
19889 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19890 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19891 GEN_INT (info->spe_gp_save_offset
19894 /* Keep the invariant that frame_reg_rtx + sp_offset points
19895 at the top of the stack frame. */
19896 sp_offset = -info->spe_gp_save_offset;
19901 if (restoring_GPRs_inline)
19903 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19904 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19906 rtx offset, addr, mem, reg;
19908 /* We're doing all this to ensure that the immediate offset
19909 fits into the immediate field of 'evldd'. */
19910 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19912 offset = GEN_INT (spe_offset + reg_size * i);
19913 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19914 mem = gen_rtx_MEM (V2SImode, addr);
19915 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19917 insn = emit_move_insn (reg, mem);
19918 if (DEFAULT_ABI == ABI_V4)
19920 if (frame_pointer_needed
19921 && info->first_gp_reg_save + i
19922 == HARD_FRAME_POINTER_REGNUM)
19924 add_reg_note (insn, REG_CFA_DEF_CFA,
19925 plus_constant (frame_reg_rtx,
19927 RTX_FRAME_RELATED_P (insn) = 1;
19930 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19939 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19941 /*savep=*/false, /*gpr=*/true,
19943 emit_jump_insn (par);
19944 /* We don't want anybody else emitting things after we jumped
19949 else if (!restoring_GPRs_inline)
19951 /* We are jumping to an out-of-line function. */
19952 bool can_use_exit = info->first_fp_reg_save == 64;
19955 /* Emit stack reset code if we need it. */
19957 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19958 sp_offset, can_use_exit);
19961 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19964 GEN_INT (sp_offset - info->fp_size)));
19965 if (REGNO (frame_reg_rtx) == 11)
19966 sp_offset += info->fp_size;
19969 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19970 info->gp_save_offset, reg_mode,
19971 /*savep=*/false, /*gpr=*/true,
19972 /*lr=*/can_use_exit);
19976 if (info->cr_save_p)
19978 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19979 if (DEFAULT_ABI == ABI_V4)
19981 = alloc_reg_note (REG_CFA_RESTORE,
19982 gen_rtx_REG (SImode, CR2_REGNO),
19986 emit_jump_insn (par);
19988 /* We don't want anybody else emitting things after we jumped
19993 insn = emit_insn (par);
19994 if (DEFAULT_ABI == ABI_V4)
19996 if (frame_pointer_needed)
19998 add_reg_note (insn, REG_CFA_DEF_CFA,
19999 plus_constant (frame_reg_rtx, sp_offset));
20000 RTX_FRAME_RELATED_P (insn) = 1;
20003 for (i = info->first_gp_reg_save; i < 32; i++)
20005 = alloc_reg_note (REG_CFA_RESTORE,
20006 gen_rtx_REG (reg_mode, i), cfa_restores);
20009 else if (using_load_multiple)
20012 p = rtvec_alloc (32 - info->first_gp_reg_save);
20013 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20015 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20016 GEN_INT (info->gp_save_offset
20019 rtx mem = gen_frame_mem (reg_mode, addr);
20020 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20022 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20023 if (DEFAULT_ABI == ABI_V4)
20024 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20027 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20028 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20030 add_reg_note (insn, REG_CFA_DEF_CFA,
20031 plus_constant (frame_reg_rtx, sp_offset));
20032 RTX_FRAME_RELATED_P (insn) = 1;
20037 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20038 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20040 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20041 GEN_INT (info->gp_save_offset
20044 rtx mem = gen_frame_mem (reg_mode, addr);
20045 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20047 insn = emit_move_insn (reg, mem);
20048 if (DEFAULT_ABI == ABI_V4)
20050 if (frame_pointer_needed
20051 && info->first_gp_reg_save + i
20052 == HARD_FRAME_POINTER_REGNUM)
20054 add_reg_note (insn, REG_CFA_DEF_CFA,
20055 plus_constant (frame_reg_rtx, sp_offset));
20056 RTX_FRAME_RELATED_P (insn) = 1;
20059 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20065 if (restore_lr && !restoring_GPRs_inline)
20067 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20068 info->lr_save_offset + sp_offset);
20070 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20071 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20072 gen_rtx_REG (Pmode, 0));
20075 /* Restore fpr's if we need to do it without calling a function. */
20076 if (restoring_FPRs_inline)
20077 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20078 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20079 && ! call_used_regs[info->first_fp_reg_save+i]))
20081 rtx addr, mem, reg;
20082 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20083 GEN_INT (info->fp_save_offset
20086 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20087 ? DFmode : SFmode), addr);
20088 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20089 ? DFmode : SFmode),
20090 info->first_fp_reg_save + i);
20092 emit_move_insn (reg, mem);
20093 if (DEFAULT_ABI == ABI_V4)
20094 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20098 /* If we saved cr, restore it here. Just those that were used. */
20099 if (info->cr_save_p)
20101 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20102 if (DEFAULT_ABI == ABI_V4)
20104 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20108 /* If this is V.4, unwind the stack pointer after all of the loads
20110 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20111 sp_offset, !restoring_FPRs_inline);
20116 REG_NOTES (insn) = cfa_restores;
20117 cfa_restores = NULL_RTX;
20119 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20120 RTX_FRAME_RELATED_P (insn) = 1;
20123 if (crtl->calls_eh_return)
20125 rtx sa = EH_RETURN_STACKADJ_RTX;
20126 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20132 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20133 if (! restoring_FPRs_inline)
20134 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20136 p = rtvec_alloc (2);
20138 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20139 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20140 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20141 : gen_rtx_CLOBBER (VOIDmode,
20142 gen_rtx_REG (Pmode, 65)));
20144 /* If we have to restore more than two FP registers, branch to the
20145 restore function. It will return to our caller. */
20146 if (! restoring_FPRs_inline)
20151 sym = rs6000_savres_routine_sym (info,
20155 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20156 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20157 gen_rtx_REG (Pmode,
20158 DEFAULT_ABI == ABI_AIX
20160 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20163 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20164 GEN_INT (info->fp_save_offset + 8*i));
20165 mem = gen_frame_mem (DFmode, addr);
20167 RTVEC_ELT (p, i+4) =
20168 gen_rtx_SET (VOIDmode,
20169 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20174 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20178 /* Write function epilogue. */
20181 rs6000_output_function_epilogue (FILE *file,
20182 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20184 if (! HAVE_epilogue)
20186 rtx insn = get_last_insn ();
20187 /* If the last insn was a BARRIER, we don't have to write anything except
20188 the trace table. */
20189 if (GET_CODE (insn) == NOTE)
20190 insn = prev_nonnote_insn (insn);
20191 if (insn == 0 || GET_CODE (insn) != BARRIER)
20193 /* This is slightly ugly, but at least we don't have two
20194 copies of the epilogue-emitting code. */
20197 /* A NOTE_INSN_DELETED is supposed to be at the start
20198 and end of the "toplevel" insn chain. */
20199 emit_note (NOTE_INSN_DELETED);
20200 rs6000_emit_epilogue (FALSE);
20201 emit_note (NOTE_INSN_DELETED);
20203 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20207 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20209 INSN_ADDRESSES_NEW (insn, addr);
20214 if (TARGET_DEBUG_STACK)
20215 debug_rtx_list (get_insns (), 100);
20216 final (get_insns (), file, FALSE);
20222 macho_branch_islands ();
20223 /* Mach-O doesn't support labels at the end of objects, so if
20224 it looks like we might want one, insert a NOP. */
20226 rtx insn = get_last_insn ();
20229 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20230 insn = PREV_INSN (insn);
20234 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20235 fputs ("\tnop\n", file);
20239 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20242 We don't output a traceback table if -finhibit-size-directive was
20243 used. The documentation for -finhibit-size-directive reads
20244 ``don't output a @code{.size} assembler directive, or anything
20245 else that would cause trouble if the function is split in the
20246 middle, and the two halves are placed at locations far apart in
20247 memory.'' The traceback table has this property, since it
20248 includes the offset from the start of the function to the
20249 traceback table itself.
20251 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20252 different traceback table. */
20253 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20254 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20256 const char *fname = NULL;
20257 const char *language_string = lang_hooks.name;
20258 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20260 int optional_tbtab;
20261 rs6000_stack_t *info = rs6000_stack_info ();
20263 if (rs6000_traceback == traceback_full)
20264 optional_tbtab = 1;
20265 else if (rs6000_traceback == traceback_part)
20266 optional_tbtab = 0;
20268 optional_tbtab = !optimize_size && !TARGET_ELF;
20270 if (optional_tbtab)
20272 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20273 while (*fname == '.') /* V.4 encodes . in the name */
20276 /* Need label immediately before tbtab, so we can compute
20277 its offset from the function start. */
20278 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20279 ASM_OUTPUT_LABEL (file, fname);
20282 /* The .tbtab pseudo-op can only be used for the first eight
20283 expressions, since it can't handle the possibly variable
20284 length fields that follow. However, if you omit the optional
20285 fields, the assembler outputs zeros for all optional fields
20286 anyways, giving each variable length field is minimum length
20287 (as defined in sys/debug.h). Thus we can not use the .tbtab
20288 pseudo-op at all. */
20290 /* An all-zero word flags the start of the tbtab, for debuggers
20291 that have to find it by searching forward from the entry
20292 point or from the current pc. */
20293 fputs ("\t.long 0\n", file);
20295 /* Tbtab format type. Use format type 0. */
20296 fputs ("\t.byte 0,", file);
20298 /* Language type. Unfortunately, there does not seem to be any
20299 official way to discover the language being compiled, so we
20300 use language_string.
20301 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20302 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20303 a number, so for now use 9. LTO isn't assigned a number either,
20304 so for now use 0. */
20305 if (! strcmp (language_string, "GNU C")
20306 || ! strcmp (language_string, "GNU GIMPLE"))
20308 else if (! strcmp (language_string, "GNU F77")
20309 || ! strcmp (language_string, "GNU Fortran"))
20311 else if (! strcmp (language_string, "GNU Pascal"))
20313 else if (! strcmp (language_string, "GNU Ada"))
20315 else if (! strcmp (language_string, "GNU C++")
20316 || ! strcmp (language_string, "GNU Objective-C++"))
20318 else if (! strcmp (language_string, "GNU Java"))
20320 else if (! strcmp (language_string, "GNU Objective-C"))
20323 gcc_unreachable ();
20324 fprintf (file, "%d,", i);
20326 /* 8 single bit fields: global linkage (not set for C extern linkage,
20327 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20328 from start of procedure stored in tbtab, internal function, function
20329 has controlled storage, function has no toc, function uses fp,
20330 function logs/aborts fp operations. */
20331 /* Assume that fp operations are used if any fp reg must be saved. */
20332 fprintf (file, "%d,",
20333 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20335 /* 6 bitfields: function is interrupt handler, name present in
20336 proc table, function calls alloca, on condition directives
20337 (controls stack walks, 3 bits), saves condition reg, saves
20339 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20340 set up as a frame pointer, even when there is no alloca call. */
20341 fprintf (file, "%d,",
20342 ((optional_tbtab << 6)
20343 | ((optional_tbtab & frame_pointer_needed) << 5)
20344 | (info->cr_save_p << 1)
20345 | (info->lr_save_p)));
20347 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20349 fprintf (file, "%d,",
20350 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20352 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20353 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20355 if (optional_tbtab)
20357 /* Compute the parameter info from the function decl argument
20360 int next_parm_info_bit = 31;
20362 for (decl = DECL_ARGUMENTS (current_function_decl);
20363 decl; decl = TREE_CHAIN (decl))
20365 rtx parameter = DECL_INCOMING_RTL (decl);
20366 enum machine_mode mode = GET_MODE (parameter);
20368 if (GET_CODE (parameter) == REG)
20370 if (SCALAR_FLOAT_MODE_P (mode))
20391 gcc_unreachable ();
20394 /* If only one bit will fit, don't or in this entry. */
20395 if (next_parm_info_bit > 0)
20396 parm_info |= (bits << (next_parm_info_bit - 1));
20397 next_parm_info_bit -= 2;
20401 fixed_parms += ((GET_MODE_SIZE (mode)
20402 + (UNITS_PER_WORD - 1))
20404 next_parm_info_bit -= 1;
20410 /* Number of fixed point parameters. */
20411 /* This is actually the number of words of fixed point parameters; thus
20412 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20413 fprintf (file, "%d,", fixed_parms);
20415 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20417 /* This is actually the number of fp registers that hold parameters;
20418 and thus the maximum value is 13. */
20419 /* Set parameters on stack bit if parameters are not in their original
20420 registers, regardless of whether they are on the stack? Xlc
20421 seems to set the bit when not optimizing. */
20422 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20424 if (! optional_tbtab)
20427 /* Optional fields follow. Some are variable length. */
20429 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20430 11 double float. */
20431 /* There is an entry for each parameter in a register, in the order that
20432 they occur in the parameter list. Any intervening arguments on the
20433 stack are ignored. If the list overflows a long (max possible length
20434 34 bits) then completely leave off all elements that don't fit. */
20435 /* Only emit this long if there was at least one parameter. */
20436 if (fixed_parms || float_parms)
20437 fprintf (file, "\t.long %d\n", parm_info);
20439 /* Offset from start of code to tb table. */
20440 fputs ("\t.long ", file);
20441 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20443 RS6000_OUTPUT_BASENAME (file, fname);
20445 assemble_name (file, fname);
20447 rs6000_output_function_entry (file, fname);
20450 /* Interrupt handler mask. */
20451 /* Omit this long, since we never set the interrupt handler bit
20454 /* Number of CTL (controlled storage) anchors. */
20455 /* Omit this long, since the has_ctl bit is never set above. */
20457 /* Displacement into stack of each CTL anchor. */
20458 /* Omit this list of longs, because there are no CTL anchors. */
20460 /* Length of function name. */
20463 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20465 /* Function name. */
20466 assemble_string (fname, strlen (fname));
20468 /* Register for alloca automatic storage; this is always reg 31.
20469 Only emit this if the alloca bit was set above. */
20470 if (frame_pointer_needed)
20471 fputs ("\t.byte 31\n", file);
20473 fputs ("\t.align 2\n", file);
20477 /* A C compound statement that outputs the assembler code for a thunk
20478 function, used to implement C++ virtual function calls with
20479 multiple inheritance. The thunk acts as a wrapper around a virtual
20480 function, adjusting the implicit object parameter before handing
20481 control off to the real function.
20483 First, emit code to add the integer DELTA to the location that
20484 contains the incoming first argument. Assume that this argument
20485 contains a pointer, and is the one used to pass the `this' pointer
20486 in C++. This is the incoming argument *before* the function
20487 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20488 values of all other incoming arguments.
20490 After the addition, emit code to jump to FUNCTION, which is a
20491 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20492 not touch the return address. Hence returning from FUNCTION will
20493 return to whoever called the current `thunk'.
20495 The effect must be as if FUNCTION had been called directly with the
20496 adjusted first argument. This macro is responsible for emitting
20497 all of the code for a thunk function; output_function_prologue()
20498 and output_function_epilogue() are not invoked.
20500 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20501 been extracted from it.) It might possibly be useful on some
20502 targets, but probably not.
20504 If you do not define this macro, the target-independent code in the
20505 C++ frontend will generate a less efficient heavyweight thunk that
20506 calls FUNCTION instead of jumping to it. The generic approach does
20507 not support varargs. */
20510 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20511 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20514 rtx this_rtx, insn, funexp;
20516 reload_completed = 1;
20517 epilogue_completed = 1;
20519 /* Mark the end of the (empty) prologue. */
20520 emit_note (NOTE_INSN_PROLOGUE_END);
20522 /* Find the "this" pointer. If the function returns a structure,
20523 the structure return pointer is in r3. */
20524 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20525 this_rtx = gen_rtx_REG (Pmode, 4);
20527 this_rtx = gen_rtx_REG (Pmode, 3);
20529 /* Apply the constant offset, if required. */
20531 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20533 /* Apply the offset from the vtable, if required. */
20536 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20537 rtx tmp = gen_rtx_REG (Pmode, 12);
20539 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20540 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20542 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20543 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20547 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20549 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20551 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20554 /* Generate a tail call to the target function. */
20555 if (!TREE_USED (function))
20557 assemble_external (function);
20558 TREE_USED (function) = 1;
20560 funexp = XEXP (DECL_RTL (function), 0);
20561 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20564 if (MACHOPIC_INDIRECT)
20565 funexp = machopic_indirect_call_target (funexp);
20568 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20569 generate sibcall RTL explicitly. */
20570 insn = emit_call_insn (
20571 gen_rtx_PARALLEL (VOIDmode,
20573 gen_rtx_CALL (VOIDmode,
20574 funexp, const0_rtx),
20575 gen_rtx_USE (VOIDmode, const0_rtx),
20576 gen_rtx_USE (VOIDmode,
20577 gen_rtx_REG (SImode,
20579 gen_rtx_RETURN (VOIDmode))));
20580 SIBLING_CALL_P (insn) = 1;
20583 /* Run just enough of rest_of_compilation to get the insns emitted.
20584 There's not really enough bulk here to make other passes such as
20585 instruction scheduling worth while. Note that use_thunk calls
20586 assemble_start_function and assemble_end_function. */
20587 insn = get_insns ();
20588 insn_locators_alloc ();
20589 shorten_branches (insn);
20590 final_start_function (insn, file, 1);
20591 final (insn, file, 1);
20592 final_end_function ();
20594 reload_completed = 0;
20595 epilogue_completed = 0;
20598 /* A quick summary of the various types of 'constant-pool tables'
20601 Target Flags Name One table per
20602 AIX (none) AIX TOC object file
20603 AIX -mfull-toc AIX TOC object file
20604 AIX -mminimal-toc AIX minimal TOC translation unit
20605 SVR4/EABI (none) SVR4 SDATA object file
20606 SVR4/EABI -fpic SVR4 pic object file
20607 SVR4/EABI -fPIC SVR4 PIC translation unit
20608 SVR4/EABI -mrelocatable EABI TOC function
20609 SVR4/EABI -maix AIX TOC object file
20610 SVR4/EABI -maix -mminimal-toc
20611 AIX minimal TOC translation unit
20613 Name Reg. Set by entries contains:
20614 made by addrs? fp? sum?
20616 AIX TOC 2 crt0 as Y option option
20617 AIX minimal TOC 30 prolog gcc Y Y option
20618 SVR4 SDATA 13 crt0 gcc N Y N
20619 SVR4 pic 30 prolog ld Y not yet N
20620 SVR4 PIC 30 prolog gcc Y option option
20621 EABI TOC 30 prolog gcc Y option option
20625 /* Hash functions for the hash table. */
20628 rs6000_hash_constant (rtx k)
20630 enum rtx_code code = GET_CODE (k);
20631 enum machine_mode mode = GET_MODE (k);
20632 unsigned result = (code << 3) ^ mode;
20633 const char *format;
20636 format = GET_RTX_FORMAT (code);
20637 flen = strlen (format);
20643 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20646 if (mode != VOIDmode)
20647 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20659 for (; fidx < flen; fidx++)
20660 switch (format[fidx])
20665 const char *str = XSTR (k, fidx);
20666 len = strlen (str);
20667 result = result * 613 + len;
20668 for (i = 0; i < len; i++)
20669 result = result * 613 + (unsigned) str[i];
20674 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20678 result = result * 613 + (unsigned) XINT (k, fidx);
20681 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20682 result = result * 613 + (unsigned) XWINT (k, fidx);
20686 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20687 result = result * 613 + (unsigned) (XWINT (k, fidx)
20694 gcc_unreachable ();
20701 toc_hash_function (const void *hash_entry)
20703 const struct toc_hash_struct *thc =
20704 (const struct toc_hash_struct *) hash_entry;
20705 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20708 /* Compare H1 and H2 for equivalence. */
20711 toc_hash_eq (const void *h1, const void *h2)
20713 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20714 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20716 if (((const struct toc_hash_struct *) h1)->key_mode
20717 != ((const struct toc_hash_struct *) h2)->key_mode)
20720 return rtx_equal_p (r1, r2);
20723 /* These are the names given by the C++ front-end to vtables, and
20724 vtable-like objects. Ideally, this logic should not be here;
20725 instead, there should be some programmatic way of inquiring as
20726 to whether or not an object is a vtable. */
20728 #define VTABLE_NAME_P(NAME) \
20729 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20730 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20731 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20732 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20733 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20735 #ifdef NO_DOLLAR_IN_LABEL
20736 /* Return a GGC-allocated character string translating dollar signs in
20737 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20740 rs6000_xcoff_strip_dollar (const char *name)
20745 p = strchr (name, '$');
20747 if (p == 0 || p == name)
20750 len = strlen (name);
20751 strip = (char *) alloca (len + 1);
20752 strcpy (strip, name);
20753 p = strchr (strip, '$');
20757 p = strchr (p + 1, '$');
20760 return ggc_alloc_string (strip, len);
20765 rs6000_output_symbol_ref (FILE *file, rtx x)
20767 /* Currently C++ toc references to vtables can be emitted before it
20768 is decided whether the vtable is public or private. If this is
20769 the case, then the linker will eventually complain that there is
20770 a reference to an unknown section. Thus, for vtables only,
20771 we emit the TOC reference to reference the symbol and not the
20773 const char *name = XSTR (x, 0);
20775 if (VTABLE_NAME_P (name))
20777 RS6000_OUTPUT_BASENAME (file, name);
20780 assemble_name (file, name);
20783 /* Output a TOC entry. We derive the entry name from what is being
20787 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20790 const char *name = buf;
20792 HOST_WIDE_INT offset = 0;
20794 gcc_assert (!TARGET_NO_TOC);
20796 /* When the linker won't eliminate them, don't output duplicate
20797 TOC entries (this happens on AIX if there is any kind of TOC,
20798 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20800 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20802 struct toc_hash_struct *h;
20805 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20806 time because GGC is not initialized at that point. */
20807 if (toc_hash_table == NULL)
20808 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20809 toc_hash_eq, NULL);
20811 h = GGC_NEW (struct toc_hash_struct);
20813 h->key_mode = mode;
20814 h->labelno = labelno;
20816 found = htab_find_slot (toc_hash_table, h, INSERT);
20817 if (*found == NULL)
20819 else /* This is indeed a duplicate.
20820 Set this label equal to that label. */
20822 fputs ("\t.set ", file);
20823 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20824 fprintf (file, "%d,", labelno);
20825 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20826 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20832 /* If we're going to put a double constant in the TOC, make sure it's
20833 aligned properly when strict alignment is on. */
20834 if (GET_CODE (x) == CONST_DOUBLE
20835 && STRICT_ALIGNMENT
20836 && GET_MODE_BITSIZE (mode) >= 64
20837 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20838 ASM_OUTPUT_ALIGN (file, 3);
20841 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20843 /* Handle FP constants specially. Note that if we have a minimal
20844 TOC, things we put here aren't actually in the TOC, so we can allow
20846 if (GET_CODE (x) == CONST_DOUBLE &&
20847 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20849 REAL_VALUE_TYPE rv;
20852 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20853 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20854 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20856 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20860 if (TARGET_MINIMAL_TOC)
20861 fputs (DOUBLE_INT_ASM_OP, file);
20863 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20864 k[0] & 0xffffffff, k[1] & 0xffffffff,
20865 k[2] & 0xffffffff, k[3] & 0xffffffff);
20866 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20867 k[0] & 0xffffffff, k[1] & 0xffffffff,
20868 k[2] & 0xffffffff, k[3] & 0xffffffff);
20873 if (TARGET_MINIMAL_TOC)
20874 fputs ("\t.long ", file);
20876 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20877 k[0] & 0xffffffff, k[1] & 0xffffffff,
20878 k[2] & 0xffffffff, k[3] & 0xffffffff);
20879 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20880 k[0] & 0xffffffff, k[1] & 0xffffffff,
20881 k[2] & 0xffffffff, k[3] & 0xffffffff);
20885 else if (GET_CODE (x) == CONST_DOUBLE &&
20886 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20888 REAL_VALUE_TYPE rv;
20891 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20893 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20894 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20896 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20900 if (TARGET_MINIMAL_TOC)
20901 fputs (DOUBLE_INT_ASM_OP, file);
20903 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20904 k[0] & 0xffffffff, k[1] & 0xffffffff);
20905 fprintf (file, "0x%lx%08lx\n",
20906 k[0] & 0xffffffff, k[1] & 0xffffffff);
20911 if (TARGET_MINIMAL_TOC)
20912 fputs ("\t.long ", file);
20914 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20915 k[0] & 0xffffffff, k[1] & 0xffffffff);
20916 fprintf (file, "0x%lx,0x%lx\n",
20917 k[0] & 0xffffffff, k[1] & 0xffffffff);
20921 else if (GET_CODE (x) == CONST_DOUBLE &&
20922 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20924 REAL_VALUE_TYPE rv;
20927 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20928 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20929 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20931 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20935 if (TARGET_MINIMAL_TOC)
20936 fputs (DOUBLE_INT_ASM_OP, file);
20938 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20939 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20944 if (TARGET_MINIMAL_TOC)
20945 fputs ("\t.long ", file);
20947 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20948 fprintf (file, "0x%lx\n", l & 0xffffffff);
20952 else if (GET_MODE (x) == VOIDmode
20953 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20955 unsigned HOST_WIDE_INT low;
20956 HOST_WIDE_INT high;
20958 if (GET_CODE (x) == CONST_DOUBLE)
20960 low = CONST_DOUBLE_LOW (x);
20961 high = CONST_DOUBLE_HIGH (x);
20964 #if HOST_BITS_PER_WIDE_INT == 32
20967 high = (low & 0x80000000) ? ~0 : 0;
20971 low = INTVAL (x) & 0xffffffff;
20972 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20976 /* TOC entries are always Pmode-sized, but since this
20977 is a bigendian machine then if we're putting smaller
20978 integer constants in the TOC we have to pad them.
20979 (This is still a win over putting the constants in
20980 a separate constant pool, because then we'd have
20981 to have both a TOC entry _and_ the actual constant.)
20983 For a 32-bit target, CONST_INT values are loaded and shifted
20984 entirely within `low' and can be stored in one TOC entry. */
20986 /* It would be easy to make this work, but it doesn't now. */
20987 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20989 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20991 #if HOST_BITS_PER_WIDE_INT == 32
20992 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20993 POINTER_SIZE, &low, &high, 0);
20996 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20997 high = (HOST_WIDE_INT) low >> 32;
21004 if (TARGET_MINIMAL_TOC)
21005 fputs (DOUBLE_INT_ASM_OP, file);
21007 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21008 (long) high & 0xffffffff, (long) low & 0xffffffff);
21009 fprintf (file, "0x%lx%08lx\n",
21010 (long) high & 0xffffffff, (long) low & 0xffffffff);
21015 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21017 if (TARGET_MINIMAL_TOC)
21018 fputs ("\t.long ", file);
21020 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21021 (long) high & 0xffffffff, (long) low & 0xffffffff);
21022 fprintf (file, "0x%lx,0x%lx\n",
21023 (long) high & 0xffffffff, (long) low & 0xffffffff);
21027 if (TARGET_MINIMAL_TOC)
21028 fputs ("\t.long ", file);
21030 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21031 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21037 if (GET_CODE (x) == CONST)
21039 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21040 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21042 base = XEXP (XEXP (x, 0), 0);
21043 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21046 switch (GET_CODE (base))
21049 name = XSTR (base, 0);
21053 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21054 CODE_LABEL_NUMBER (XEXP (base, 0)));
21058 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21062 gcc_unreachable ();
21065 if (TARGET_MINIMAL_TOC)
21066 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21069 fputs ("\t.tc ", file);
21070 RS6000_OUTPUT_BASENAME (file, name);
21073 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21075 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21077 fputs ("[TC],", file);
21080 /* Currently C++ toc references to vtables can be emitted before it
21081 is decided whether the vtable is public or private. If this is
21082 the case, then the linker will eventually complain that there is
21083 a TOC reference to an unknown section. Thus, for vtables only,
21084 we emit the TOC reference to reference the symbol and not the
21086 if (VTABLE_NAME_P (name))
21088 RS6000_OUTPUT_BASENAME (file, name);
21090 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21091 else if (offset > 0)
21092 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21095 output_addr_const (file, x);
21099 /* Output an assembler pseudo-op to write an ASCII string of N characters
21100 starting at P to FILE.
21102 On the RS/6000, we have to do this using the .byte operation and
21103 write out special characters outside the quoted string.
21104 Also, the assembler is broken; very long strings are truncated,
21105 so we must artificially break them up early. */
21108 output_ascii (FILE *file, const char *p, int n)
21111 int i, count_string;
21112 const char *for_string = "\t.byte \"";
21113 const char *for_decimal = "\t.byte ";
21114 const char *to_close = NULL;
21117 for (i = 0; i < n; i++)
21120 if (c >= ' ' && c < 0177)
21123 fputs (for_string, file);
21126 /* Write two quotes to get one. */
21134 for_decimal = "\"\n\t.byte ";
21138 if (count_string >= 512)
21140 fputs (to_close, file);
21142 for_string = "\t.byte \"";
21143 for_decimal = "\t.byte ";
21151 fputs (for_decimal, file);
21152 fprintf (file, "%d", c);
21154 for_string = "\n\t.byte \"";
21155 for_decimal = ", ";
21161 /* Now close the string if we have written one. Then end the line. */
21163 fputs (to_close, file);
21166 /* Generate a unique section name for FILENAME for a section type
21167 represented by SECTION_DESC. Output goes into BUF.
21169 SECTION_DESC can be any string, as long as it is different for each
21170 possible section type.
21172 We name the section in the same manner as xlc. The name begins with an
21173 underscore followed by the filename (after stripping any leading directory
21174 names) with the last period replaced by the string SECTION_DESC. If
21175 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21179 rs6000_gen_section_name (char **buf, const char *filename,
21180 const char *section_desc)
21182 const char *q, *after_last_slash, *last_period = 0;
21186 after_last_slash = filename;
21187 for (q = filename; *q; q++)
21190 after_last_slash = q + 1;
21191 else if (*q == '.')
21195 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21196 *buf = (char *) xmalloc (len);
21201 for (q = after_last_slash; *q; q++)
21203 if (q == last_period)
21205 strcpy (p, section_desc);
21206 p += strlen (section_desc);
21210 else if (ISALNUM (*q))
21214 if (last_period == 0)
21215 strcpy (p, section_desc);
21220 /* Emit profile function. */
21223 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21225 /* Non-standard profiling for kernels, which just saves LR then calls
21226 _mcount without worrying about arg saves. The idea is to change
21227 the function prologue as little as possible as it isn't easy to
21228 account for arg save/restore code added just for _mcount. */
21229 if (TARGET_PROFILE_KERNEL)
21232 if (DEFAULT_ABI == ABI_AIX)
21234 #ifndef NO_PROFILE_COUNTERS
21235 # define NO_PROFILE_COUNTERS 0
21237 if (NO_PROFILE_COUNTERS)
21238 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21239 LCT_NORMAL, VOIDmode, 0);
21243 const char *label_name;
21246 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21247 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21248 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21250 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21251 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21254 else if (DEFAULT_ABI == ABI_DARWIN)
21256 const char *mcount_name = RS6000_MCOUNT;
21257 int caller_addr_regno = LR_REGNO;
21259 /* Be conservative and always set this, at least for now. */
21260 crtl->uses_pic_offset_table = 1;
21263 /* For PIC code, set up a stub and collect the caller's address
21264 from r0, which is where the prologue puts it. */
21265 if (MACHOPIC_INDIRECT
21266 && crtl->uses_pic_offset_table)
21267 caller_addr_regno = 0;
21269 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21270 LCT_NORMAL, VOIDmode, 1,
21271 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21275 /* Write function profiler code. */
21278 output_function_profiler (FILE *file, int labelno)
21282 switch (DEFAULT_ABI)
21285 gcc_unreachable ();
21290 warning (0, "no profiling of 64-bit code for this ABI");
21293 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21294 fprintf (file, "\tmflr %s\n", reg_names[0]);
21295 if (NO_PROFILE_COUNTERS)
21297 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21298 reg_names[0], reg_names[1]);
21300 else if (TARGET_SECURE_PLT && flag_pic)
21302 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21303 reg_names[0], reg_names[1]);
21304 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21305 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21306 reg_names[12], reg_names[12]);
21307 assemble_name (file, buf);
21308 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21309 assemble_name (file, buf);
21310 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21312 else if (flag_pic == 1)
21314 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21315 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21316 reg_names[0], reg_names[1]);
21317 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21318 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21319 assemble_name (file, buf);
21320 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21322 else if (flag_pic > 1)
21324 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21325 reg_names[0], reg_names[1]);
21326 /* Now, we need to get the address of the label. */
21327 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21328 assemble_name (file, buf);
21329 fputs ("-.\n1:", file);
21330 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21331 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21332 reg_names[0], reg_names[11]);
21333 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21334 reg_names[0], reg_names[0], reg_names[11]);
21338 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21339 assemble_name (file, buf);
21340 fputs ("@ha\n", file);
21341 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21342 reg_names[0], reg_names[1]);
21343 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21344 assemble_name (file, buf);
21345 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21348 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21349 fprintf (file, "\tbl %s%s\n",
21350 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21355 if (!TARGET_PROFILE_KERNEL)
21357 /* Don't do anything, done in output_profile_hook (). */
21361 gcc_assert (!TARGET_32BIT);
21363 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21364 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21366 if (cfun->static_chain_decl != NULL)
21368 asm_fprintf (file, "\tstd %s,24(%s)\n",
21369 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21370 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21371 asm_fprintf (file, "\tld %s,24(%s)\n",
21372 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21375 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21383 /* The following variable value is the last issued insn. */
21385 static rtx last_scheduled_insn;
21387 /* The following variable helps to balance issuing of load and
21388 store instructions */
21390 static int load_store_pendulum;
21392 /* Power4 load update and store update instructions are cracked into a
21393 load or store and an integer insn which are executed in the same cycle.
21394 Branches have their own dispatch slot which does not count against the
21395 GCC issue rate, but it changes the program flow so there are no other
21396 instructions to issue in this cycle. */
21399 rs6000_variable_issue_1 (rtx insn, int more)
21401 last_scheduled_insn = insn;
21402 if (GET_CODE (PATTERN (insn)) == USE
21403 || GET_CODE (PATTERN (insn)) == CLOBBER)
21405 cached_can_issue_more = more;
21406 return cached_can_issue_more;
21409 if (insn_terminates_group_p (insn, current_group))
21411 cached_can_issue_more = 0;
21412 return cached_can_issue_more;
21415 /* If no reservation, but reach here */
21416 if (recog_memoized (insn) < 0)
21419 if (rs6000_sched_groups)
21421 if (is_microcoded_insn (insn))
21422 cached_can_issue_more = 0;
21423 else if (is_cracked_insn (insn))
21424 cached_can_issue_more = more > 2 ? more - 2 : 0;
21426 cached_can_issue_more = more - 1;
21428 return cached_can_issue_more;
21431 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21434 cached_can_issue_more = more - 1;
21435 return cached_can_issue_more;
21439 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21441 int r = rs6000_variable_issue_1 (insn, more);
21443 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21447 /* Adjust the cost of a scheduling dependency. Return the new cost of
21448 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21451 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21453 enum attr_type attr_type;
21455 if (! recog_memoized (insn))
21458 switch (REG_NOTE_KIND (link))
21462 /* Data dependency; DEP_INSN writes a register that INSN reads
21463 some cycles later. */
21465 /* Separate a load from a narrower, dependent store. */
21466 if (rs6000_sched_groups
21467 && GET_CODE (PATTERN (insn)) == SET
21468 && GET_CODE (PATTERN (dep_insn)) == SET
21469 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21470 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21471 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21472 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21475 attr_type = get_attr_type (insn);
21480 /* Tell the first scheduling pass about the latency between
21481 a mtctr and bctr (and mtlr and br/blr). The first
21482 scheduling pass will not know about this latency since
21483 the mtctr instruction, which has the latency associated
21484 to it, will be generated by reload. */
21485 return TARGET_POWER ? 5 : 4;
21487 /* Leave some extra cycles between a compare and its
21488 dependent branch, to inhibit expensive mispredicts. */
21489 if ((rs6000_cpu_attr == CPU_PPC603
21490 || rs6000_cpu_attr == CPU_PPC604
21491 || rs6000_cpu_attr == CPU_PPC604E
21492 || rs6000_cpu_attr == CPU_PPC620
21493 || rs6000_cpu_attr == CPU_PPC630
21494 || rs6000_cpu_attr == CPU_PPC750
21495 || rs6000_cpu_attr == CPU_PPC7400
21496 || rs6000_cpu_attr == CPU_PPC7450
21497 || rs6000_cpu_attr == CPU_POWER4
21498 || rs6000_cpu_attr == CPU_POWER5
21499 || rs6000_cpu_attr == CPU_POWER7
21500 || rs6000_cpu_attr == CPU_CELL)
21501 && recog_memoized (dep_insn)
21502 && (INSN_CODE (dep_insn) >= 0))
21504 switch (get_attr_type (dep_insn))
21508 case TYPE_DELAYED_COMPARE:
21509 case TYPE_IMUL_COMPARE:
21510 case TYPE_LMUL_COMPARE:
21511 case TYPE_FPCOMPARE:
21512 case TYPE_CR_LOGICAL:
21513 case TYPE_DELAYED_CR:
21522 case TYPE_STORE_UX:
21524 case TYPE_FPSTORE_U:
21525 case TYPE_FPSTORE_UX:
21526 if ((rs6000_cpu == PROCESSOR_POWER6)
21527 && recog_memoized (dep_insn)
21528 && (INSN_CODE (dep_insn) >= 0))
21531 if (GET_CODE (PATTERN (insn)) != SET)
21532 /* If this happens, we have to extend this to schedule
21533 optimally. Return default for now. */
21536 /* Adjust the cost for the case where the value written
21537 by a fixed point operation is used as the address
21538 gen value on a store. */
21539 switch (get_attr_type (dep_insn))
21546 if (! store_data_bypass_p (dep_insn, insn))
21550 case TYPE_LOAD_EXT:
21551 case TYPE_LOAD_EXT_U:
21552 case TYPE_LOAD_EXT_UX:
21553 case TYPE_VAR_SHIFT_ROTATE:
21554 case TYPE_VAR_DELAYED_COMPARE:
21556 if (! store_data_bypass_p (dep_insn, insn))
21562 case TYPE_FAST_COMPARE:
21565 case TYPE_INSERT_WORD:
21566 case TYPE_INSERT_DWORD:
21567 case TYPE_FPLOAD_U:
21568 case TYPE_FPLOAD_UX:
21570 case TYPE_STORE_UX:
21571 case TYPE_FPSTORE_U:
21572 case TYPE_FPSTORE_UX:
21574 if (! store_data_bypass_p (dep_insn, insn))
21582 case TYPE_IMUL_COMPARE:
21583 case TYPE_LMUL_COMPARE:
21585 if (! store_data_bypass_p (dep_insn, insn))
21591 if (! store_data_bypass_p (dep_insn, insn))
21597 if (! store_data_bypass_p (dep_insn, insn))
21610 case TYPE_LOAD_EXT:
21611 case TYPE_LOAD_EXT_U:
21612 case TYPE_LOAD_EXT_UX:
21613 if ((rs6000_cpu == PROCESSOR_POWER6)
21614 && recog_memoized (dep_insn)
21615 && (INSN_CODE (dep_insn) >= 0))
21618 /* Adjust the cost for the case where the value written
21619 by a fixed point instruction is used within the address
21620 gen portion of a subsequent load(u)(x) */
21621 switch (get_attr_type (dep_insn))
21628 if (set_to_load_agen (dep_insn, insn))
21632 case TYPE_LOAD_EXT:
21633 case TYPE_LOAD_EXT_U:
21634 case TYPE_LOAD_EXT_UX:
21635 case TYPE_VAR_SHIFT_ROTATE:
21636 case TYPE_VAR_DELAYED_COMPARE:
21638 if (set_to_load_agen (dep_insn, insn))
21644 case TYPE_FAST_COMPARE:
21647 case TYPE_INSERT_WORD:
21648 case TYPE_INSERT_DWORD:
21649 case TYPE_FPLOAD_U:
21650 case TYPE_FPLOAD_UX:
21652 case TYPE_STORE_UX:
21653 case TYPE_FPSTORE_U:
21654 case TYPE_FPSTORE_UX:
21656 if (set_to_load_agen (dep_insn, insn))
21664 case TYPE_IMUL_COMPARE:
21665 case TYPE_LMUL_COMPARE:
21667 if (set_to_load_agen (dep_insn, insn))
21673 if (set_to_load_agen (dep_insn, insn))
21679 if (set_to_load_agen (dep_insn, insn))
21690 if ((rs6000_cpu == PROCESSOR_POWER6)
21691 && recog_memoized (dep_insn)
21692 && (INSN_CODE (dep_insn) >= 0)
21693 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21700 /* Fall out to return default cost. */
21704 case REG_DEP_OUTPUT:
21705 /* Output dependency; DEP_INSN writes a register that INSN writes some
21707 if ((rs6000_cpu == PROCESSOR_POWER6)
21708 && recog_memoized (dep_insn)
21709 && (INSN_CODE (dep_insn) >= 0))
21711 attr_type = get_attr_type (insn);
21716 if (get_attr_type (dep_insn) == TYPE_FP)
21720 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21728 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21733 gcc_unreachable ();
21739 /* Debug version of rs6000_adjust_cost. */
21742 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21744 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21750 switch (REG_NOTE_KIND (link))
21752 default: dep = "unknown depencency"; break;
21753 case REG_DEP_TRUE: dep = "data dependency"; break;
21754 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21755 case REG_DEP_ANTI: dep = "anti depencency"; break;
21759 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21760 "%s, insn:\n", ret, cost, dep);
21768 /* The function returns a true if INSN is microcoded.
21769 Return false otherwise. */
21772 is_microcoded_insn (rtx insn)
21774 if (!insn || !NONDEBUG_INSN_P (insn)
21775 || GET_CODE (PATTERN (insn)) == USE
21776 || GET_CODE (PATTERN (insn)) == CLOBBER)
21779 if (rs6000_cpu_attr == CPU_CELL)
21780 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21782 if (rs6000_sched_groups)
21784 enum attr_type type = get_attr_type (insn);
21785 if (type == TYPE_LOAD_EXT_U
21786 || type == TYPE_LOAD_EXT_UX
21787 || type == TYPE_LOAD_UX
21788 || type == TYPE_STORE_UX
21789 || type == TYPE_MFCR)
21796 /* The function returns true if INSN is cracked into 2 instructions
21797 by the processor (and therefore occupies 2 issue slots). */
21800 is_cracked_insn (rtx insn)
21802 if (!insn || !NONDEBUG_INSN_P (insn)
21803 || GET_CODE (PATTERN (insn)) == USE
21804 || GET_CODE (PATTERN (insn)) == CLOBBER)
21807 if (rs6000_sched_groups)
21809 enum attr_type type = get_attr_type (insn);
21810 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21811 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21812 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21813 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21814 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21815 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21816 || type == TYPE_IDIV || type == TYPE_LDIV
21817 || type == TYPE_INSERT_WORD)
21824 /* The function returns true if INSN can be issued only from
21825 the branch slot. */
21828 is_branch_slot_insn (rtx insn)
21830 if (!insn || !NONDEBUG_INSN_P (insn)
21831 || GET_CODE (PATTERN (insn)) == USE
21832 || GET_CODE (PATTERN (insn)) == CLOBBER)
21835 if (rs6000_sched_groups)
21837 enum attr_type type = get_attr_type (insn);
21838 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21846 /* The function returns true if out_inst sets a value that is
21847 used in the address generation computation of in_insn */
21849 set_to_load_agen (rtx out_insn, rtx in_insn)
21851 rtx out_set, in_set;
21853 /* For performance reasons, only handle the simple case where
21854 both loads are a single_set. */
21855 out_set = single_set (out_insn);
21858 in_set = single_set (in_insn);
21860 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21866 /* The function returns true if the target storage location of
21867 out_insn is adjacent to the target storage location of in_insn */
21868 /* Return 1 if memory locations are adjacent. */
21871 adjacent_mem_locations (rtx insn1, rtx insn2)
21874 rtx a = get_store_dest (PATTERN (insn1));
21875 rtx b = get_store_dest (PATTERN (insn2));
21877 if ((GET_CODE (XEXP (a, 0)) == REG
21878 || (GET_CODE (XEXP (a, 0)) == PLUS
21879 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21880 && (GET_CODE (XEXP (b, 0)) == REG
21881 || (GET_CODE (XEXP (b, 0)) == PLUS
21882 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21884 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21887 if (GET_CODE (XEXP (a, 0)) == PLUS)
21889 reg0 = XEXP (XEXP (a, 0), 0);
21890 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21893 reg0 = XEXP (a, 0);
21895 if (GET_CODE (XEXP (b, 0)) == PLUS)
21897 reg1 = XEXP (XEXP (b, 0), 0);
21898 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21901 reg1 = XEXP (b, 0);
21903 val_diff = val1 - val0;
21905 return ((REGNO (reg0) == REGNO (reg1))
21906 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21907 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21913 /* A C statement (sans semicolon) to update the integer scheduling
21914 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21915 INSN earlier, reduce the priority to execute INSN later. Do not
21916 define this macro if you do not need to adjust the scheduling
21917 priorities of insns. */
21920 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21922 /* On machines (like the 750) which have asymmetric integer units,
21923 where one integer unit can do multiply and divides and the other
21924 can't, reduce the priority of multiply/divide so it is scheduled
21925 before other integer operations. */
21928 if (! INSN_P (insn))
21931 if (GET_CODE (PATTERN (insn)) == USE)
21934 switch (rs6000_cpu_attr) {
21936 switch (get_attr_type (insn))
21943 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21944 priority, priority);
21945 if (priority >= 0 && priority < 0x01000000)
21952 if (insn_must_be_first_in_group (insn)
21953 && reload_completed
21954 && current_sched_info->sched_max_insns_priority
21955 && rs6000_sched_restricted_insns_priority)
21958 /* Prioritize insns that can be dispatched only in the first
21960 if (rs6000_sched_restricted_insns_priority == 1)
21961 /* Attach highest priority to insn. This means that in
21962 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21963 precede 'priority' (critical path) considerations. */
21964 return current_sched_info->sched_max_insns_priority;
21965 else if (rs6000_sched_restricted_insns_priority == 2)
21966 /* Increase priority of insn by a minimal amount. This means that in
21967 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21968 considerations precede dispatch-slot restriction considerations. */
21969 return (priority + 1);
21972 if (rs6000_cpu == PROCESSOR_POWER6
21973 && ((load_store_pendulum == -2 && is_load_insn (insn))
21974 || (load_store_pendulum == 2 && is_store_insn (insn))))
21975 /* Attach highest priority to insn if the scheduler has just issued two
21976 stores and this instruction is a load, or two loads and this instruction
21977 is a store. Power6 wants loads and stores scheduled alternately
21979 return current_sched_info->sched_max_insns_priority;
21984 /* Return true if the instruction is nonpipelined on the Cell. */
21986 is_nonpipeline_insn (rtx insn)
21988 enum attr_type type;
21989 if (!insn || !NONDEBUG_INSN_P (insn)
21990 || GET_CODE (PATTERN (insn)) == USE
21991 || GET_CODE (PATTERN (insn)) == CLOBBER)
21994 type = get_attr_type (insn);
21995 if (type == TYPE_IMUL
21996 || type == TYPE_IMUL2
21997 || type == TYPE_IMUL3
21998 || type == TYPE_LMUL
21999 || type == TYPE_IDIV
22000 || type == TYPE_LDIV
22001 || type == TYPE_SDIV
22002 || type == TYPE_DDIV
22003 || type == TYPE_SSQRT
22004 || type == TYPE_DSQRT
22005 || type == TYPE_MFCR
22006 || type == TYPE_MFCRF
22007 || type == TYPE_MFJMPR)
22015 /* Return how many instructions the machine can issue per cycle. */
22018 rs6000_issue_rate (void)
22020 /* Unless scheduling for register pressure, use issue rate of 1 for
22021 first scheduling pass to decrease degradation. */
22022 if (!reload_completed && !flag_sched_pressure)
22025 switch (rs6000_cpu_attr) {
22026 case CPU_RIOS1: /* ? */
22028 case CPU_PPC601: /* ? */
22037 case CPU_PPCE300C2:
22038 case CPU_PPCE300C3:
22039 case CPU_PPCE500MC:
22040 case CPU_PPCE500MC64:
22059 /* Return how many instructions to look ahead for better insn
22063 rs6000_use_sched_lookahead (void)
22065 if (rs6000_cpu_attr == CPU_PPC8540)
22067 if (rs6000_cpu_attr == CPU_CELL)
22068 return (reload_completed ? 8 : 0);
22072 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22074 rs6000_use_sched_lookahead_guard (rtx insn)
22076 if (rs6000_cpu_attr != CPU_CELL)
22079 if (insn == NULL_RTX || !INSN_P (insn))
22082 if (!reload_completed
22083 || is_nonpipeline_insn (insn)
22084 || is_microcoded_insn (insn))
22090 /* Determine is PAT refers to memory. */
22093 is_mem_ref (rtx pat)
22099 /* stack_tie does not produce any real memory traffic. */
22100 if (GET_CODE (pat) == UNSPEC
22101 && XINT (pat, 1) == UNSPEC_TIE)
22104 if (GET_CODE (pat) == MEM)
22107 /* Recursively process the pattern. */
22108 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22110 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22113 ret |= is_mem_ref (XEXP (pat, i));
22114 else if (fmt[i] == 'E')
22115 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22116 ret |= is_mem_ref (XVECEXP (pat, i, j));
22122 /* Determine if PAT is a PATTERN of a load insn. */
22125 is_load_insn1 (rtx pat)
22127 if (!pat || pat == NULL_RTX)
22130 if (GET_CODE (pat) == SET)
22131 return is_mem_ref (SET_SRC (pat));
22133 if (GET_CODE (pat) == PARALLEL)
22137 for (i = 0; i < XVECLEN (pat, 0); i++)
22138 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22145 /* Determine if INSN loads from memory. */
22148 is_load_insn (rtx insn)
22150 if (!insn || !INSN_P (insn))
22153 if (GET_CODE (insn) == CALL_INSN)
22156 return is_load_insn1 (PATTERN (insn));
22159 /* Determine if PAT is a PATTERN of a store insn. */
22162 is_store_insn1 (rtx pat)
22164 if (!pat || pat == NULL_RTX)
22167 if (GET_CODE (pat) == SET)
22168 return is_mem_ref (SET_DEST (pat));
22170 if (GET_CODE (pat) == PARALLEL)
22174 for (i = 0; i < XVECLEN (pat, 0); i++)
22175 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22182 /* Determine if INSN stores to memory. */
22185 is_store_insn (rtx insn)
22187 if (!insn || !INSN_P (insn))
22190 return is_store_insn1 (PATTERN (insn));
22193 /* Return the dest of a store insn. */
22196 get_store_dest (rtx pat)
22198 gcc_assert (is_store_insn1 (pat));
22200 if (GET_CODE (pat) == SET)
22201 return SET_DEST (pat);
22202 else if (GET_CODE (pat) == PARALLEL)
22206 for (i = 0; i < XVECLEN (pat, 0); i++)
22208 rtx inner_pat = XVECEXP (pat, 0, i);
22209 if (GET_CODE (inner_pat) == SET
22210 && is_mem_ref (SET_DEST (inner_pat)))
22214 /* We shouldn't get here, because we should have either a simple
22215 store insn or a store with update which are covered above. */
22219 /* Returns whether the dependence between INSN and NEXT is considered
22220 costly by the given target. */
22223 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22228 /* If the flag is not enabled - no dependence is considered costly;
22229 allow all dependent insns in the same group.
22230 This is the most aggressive option. */
22231 if (rs6000_sched_costly_dep == no_dep_costly)
22234 /* If the flag is set to 1 - a dependence is always considered costly;
22235 do not allow dependent instructions in the same group.
22236 This is the most conservative option. */
22237 if (rs6000_sched_costly_dep == all_deps_costly)
22240 insn = DEP_PRO (dep);
22241 next = DEP_CON (dep);
22243 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22244 && is_load_insn (next)
22245 && is_store_insn (insn))
22246 /* Prevent load after store in the same group. */
22249 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22250 && is_load_insn (next)
22251 && is_store_insn (insn)
22252 && DEP_TYPE (dep) == REG_DEP_TRUE)
22253 /* Prevent load after store in the same group if it is a true
22257 /* The flag is set to X; dependences with latency >= X are considered costly,
22258 and will not be scheduled in the same group. */
22259 if (rs6000_sched_costly_dep <= max_dep_latency
22260 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22266 /* Return the next insn after INSN that is found before TAIL is reached,
22267 skipping any "non-active" insns - insns that will not actually occupy
22268 an issue slot. Return NULL_RTX if such an insn is not found. */
22271 get_next_active_insn (rtx insn, rtx tail)
22273 if (insn == NULL_RTX || insn == tail)
22278 insn = NEXT_INSN (insn);
22279 if (insn == NULL_RTX || insn == tail)
22284 || (NONJUMP_INSN_P (insn)
22285 && GET_CODE (PATTERN (insn)) != USE
22286 && GET_CODE (PATTERN (insn)) != CLOBBER
22287 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22293 /* We are about to begin issuing insns for this clock cycle. */
22296 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22297 rtx *ready ATTRIBUTE_UNUSED,
22298 int *pn_ready ATTRIBUTE_UNUSED,
22299 int clock_var ATTRIBUTE_UNUSED)
22301 int n_ready = *pn_ready;
22304 fprintf (dump, "// rs6000_sched_reorder :\n");
22306 /* Reorder the ready list, if the second to last ready insn
22307 is a nonepipeline insn. */
22308 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22310 if (is_nonpipeline_insn (ready[n_ready - 1])
22311 && (recog_memoized (ready[n_ready - 2]) > 0))
22312 /* Simply swap first two insns. */
22314 rtx tmp = ready[n_ready - 1];
22315 ready[n_ready - 1] = ready[n_ready - 2];
22316 ready[n_ready - 2] = tmp;
22320 if (rs6000_cpu == PROCESSOR_POWER6)
22321 load_store_pendulum = 0;
22323 return rs6000_issue_rate ();
22326 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22329 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22330 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22333 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22335 /* For Power6, we need to handle some special cases to try and keep the
22336 store queue from overflowing and triggering expensive flushes.
22338 This code monitors how load and store instructions are being issued
22339 and skews the ready list one way or the other to increase the likelihood
22340 that a desired instruction is issued at the proper time.
22342 A couple of things are done. First, we maintain a "load_store_pendulum"
22343 to track the current state of load/store issue.
22345 - If the pendulum is at zero, then no loads or stores have been
22346 issued in the current cycle so we do nothing.
22348 - If the pendulum is 1, then a single load has been issued in this
22349 cycle and we attempt to locate another load in the ready list to
22352 - If the pendulum is -2, then two stores have already been
22353 issued in this cycle, so we increase the priority of the first load
22354 in the ready list to increase it's likelihood of being chosen first
22357 - If the pendulum is -1, then a single store has been issued in this
22358 cycle and we attempt to locate another store in the ready list to
22359 issue with it, preferring a store to an adjacent memory location to
22360 facilitate store pairing in the store queue.
22362 - If the pendulum is 2, then two loads have already been
22363 issued in this cycle, so we increase the priority of the first store
22364 in the ready list to increase it's likelihood of being chosen first
22367 - If the pendulum < -2 or > 2, then do nothing.
22369 Note: This code covers the most common scenarios. There exist non
22370 load/store instructions which make use of the LSU and which
22371 would need to be accounted for to strictly model the behavior
22372 of the machine. Those instructions are currently unaccounted
22373 for to help minimize compile time overhead of this code.
22375 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22381 if (is_store_insn (last_scheduled_insn))
22382 /* Issuing a store, swing the load_store_pendulum to the left */
22383 load_store_pendulum--;
22384 else if (is_load_insn (last_scheduled_insn))
22385 /* Issuing a load, swing the load_store_pendulum to the right */
22386 load_store_pendulum++;
22388 return cached_can_issue_more;
22390 /* If the pendulum is balanced, or there is only one instruction on
22391 the ready list, then all is well, so return. */
22392 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22393 return cached_can_issue_more;
22395 if (load_store_pendulum == 1)
22397 /* A load has been issued in this cycle. Scan the ready list
22398 for another load to issue with it */
22403 if (is_load_insn (ready[pos]))
22405 /* Found a load. Move it to the head of the ready list,
22406 and adjust it's priority so that it is more likely to
22409 for (i=pos; i<*pn_ready-1; i++)
22410 ready[i] = ready[i + 1];
22411 ready[*pn_ready-1] = tmp;
22413 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22414 INSN_PRIORITY (tmp)++;
22420 else if (load_store_pendulum == -2)
22422 /* Two stores have been issued in this cycle. Increase the
22423 priority of the first load in the ready list to favor it for
22424 issuing in the next cycle. */
22429 if (is_load_insn (ready[pos])
22431 && INSN_PRIORITY_KNOWN (ready[pos]))
22433 INSN_PRIORITY (ready[pos])++;
22435 /* Adjust the pendulum to account for the fact that a load
22436 was found and increased in priority. This is to prevent
22437 increasing the priority of multiple loads */
22438 load_store_pendulum--;
22445 else if (load_store_pendulum == -1)
22447 /* A store has been issued in this cycle. Scan the ready list for
22448 another store to issue with it, preferring a store to an adjacent
22450 int first_store_pos = -1;
22456 if (is_store_insn (ready[pos]))
22458 /* Maintain the index of the first store found on the
22460 if (first_store_pos == -1)
22461 first_store_pos = pos;
22463 if (is_store_insn (last_scheduled_insn)
22464 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22466 /* Found an adjacent store. Move it to the head of the
22467 ready list, and adjust it's priority so that it is
22468 more likely to stay there */
22470 for (i=pos; i<*pn_ready-1; i++)
22471 ready[i] = ready[i + 1];
22472 ready[*pn_ready-1] = tmp;
22474 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22475 INSN_PRIORITY (tmp)++;
22477 first_store_pos = -1;
22485 if (first_store_pos >= 0)
22487 /* An adjacent store wasn't found, but a non-adjacent store was,
22488 so move the non-adjacent store to the front of the ready
22489 list, and adjust its priority so that it is more likely to
22491 tmp = ready[first_store_pos];
22492 for (i=first_store_pos; i<*pn_ready-1; i++)
22493 ready[i] = ready[i + 1];
22494 ready[*pn_ready-1] = tmp;
22495 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22496 INSN_PRIORITY (tmp)++;
22499 else if (load_store_pendulum == 2)
22501 /* Two loads have been issued in this cycle. Increase the priority
22502 of the first store in the ready list to favor it for issuing in
22508 if (is_store_insn (ready[pos])
22510 && INSN_PRIORITY_KNOWN (ready[pos]))
22512 INSN_PRIORITY (ready[pos])++;
22514 /* Adjust the pendulum to account for the fact that a store
22515 was found and increased in priority. This is to prevent
22516 increasing the priority of multiple stores */
22517 load_store_pendulum++;
22526 return cached_can_issue_more;
22529 /* Return whether the presence of INSN causes a dispatch group termination
22530 of group WHICH_GROUP.
22532 If WHICH_GROUP == current_group, this function will return true if INSN
22533 causes the termination of the current group (i.e, the dispatch group to
22534 which INSN belongs). This means that INSN will be the last insn in the
22535 group it belongs to.
22537 If WHICH_GROUP == previous_group, this function will return true if INSN
22538 causes the termination of the previous group (i.e, the dispatch group that
22539 precedes the group to which INSN belongs). This means that INSN will be
22540 the first insn in the group it belongs to). */
22543 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22550 first = insn_must_be_first_in_group (insn);
22551 last = insn_must_be_last_in_group (insn);
22556 if (which_group == current_group)
22558 else if (which_group == previous_group)
22566 insn_must_be_first_in_group (rtx insn)
22568 enum attr_type type;
22571 || GET_CODE (insn) == NOTE
22572 || DEBUG_INSN_P (insn)
22573 || GET_CODE (PATTERN (insn)) == USE
22574 || GET_CODE (PATTERN (insn)) == CLOBBER)
22577 switch (rs6000_cpu)
22579 case PROCESSOR_POWER5:
22580 if (is_cracked_insn (insn))
22582 case PROCESSOR_POWER4:
22583 if (is_microcoded_insn (insn))
22586 if (!rs6000_sched_groups)
22589 type = get_attr_type (insn);
22596 case TYPE_DELAYED_CR:
22597 case TYPE_CR_LOGICAL:
22611 case PROCESSOR_POWER6:
22612 type = get_attr_type (insn);
22616 case TYPE_INSERT_DWORD:
22620 case TYPE_VAR_SHIFT_ROTATE:
22627 case TYPE_INSERT_WORD:
22628 case TYPE_DELAYED_COMPARE:
22629 case TYPE_IMUL_COMPARE:
22630 case TYPE_LMUL_COMPARE:
22631 case TYPE_FPCOMPARE:
22642 case TYPE_LOAD_EXT_UX:
22644 case TYPE_STORE_UX:
22645 case TYPE_FPLOAD_U:
22646 case TYPE_FPLOAD_UX:
22647 case TYPE_FPSTORE_U:
22648 case TYPE_FPSTORE_UX:
22654 case PROCESSOR_POWER7:
22655 type = get_attr_type (insn);
22659 case TYPE_CR_LOGICAL:
22666 case TYPE_DELAYED_COMPARE:
22667 case TYPE_VAR_DELAYED_COMPARE:
22673 case TYPE_LOAD_EXT:
22674 case TYPE_LOAD_EXT_U:
22675 case TYPE_LOAD_EXT_UX:
22677 case TYPE_STORE_UX:
22678 case TYPE_FPLOAD_U:
22679 case TYPE_FPLOAD_UX:
22680 case TYPE_FPSTORE_U:
22681 case TYPE_FPSTORE_UX:
22697 insn_must_be_last_in_group (rtx insn)
22699 enum attr_type type;
22702 || GET_CODE (insn) == NOTE
22703 || DEBUG_INSN_P (insn)
22704 || GET_CODE (PATTERN (insn)) == USE
22705 || GET_CODE (PATTERN (insn)) == CLOBBER)
22708 switch (rs6000_cpu) {
22709 case PROCESSOR_POWER4:
22710 case PROCESSOR_POWER5:
22711 if (is_microcoded_insn (insn))
22714 if (is_branch_slot_insn (insn))
22718 case PROCESSOR_POWER6:
22719 type = get_attr_type (insn);
22726 case TYPE_VAR_SHIFT_ROTATE:
22733 case TYPE_DELAYED_COMPARE:
22734 case TYPE_IMUL_COMPARE:
22735 case TYPE_LMUL_COMPARE:
22736 case TYPE_FPCOMPARE:
22750 case PROCESSOR_POWER7:
22751 type = get_attr_type (insn);
22759 case TYPE_LOAD_EXT_U:
22760 case TYPE_LOAD_EXT_UX:
22761 case TYPE_STORE_UX:
22774 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22775 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22778 is_costly_group (rtx *group_insns, rtx next_insn)
22781 int issue_rate = rs6000_issue_rate ();
22783 for (i = 0; i < issue_rate; i++)
22785 sd_iterator_def sd_it;
22787 rtx insn = group_insns[i];
22792 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22794 rtx next = DEP_CON (dep);
22796 if (next == next_insn
22797 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22805 /* Utility of the function redefine_groups.
22806 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22807 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22808 to keep it "far" (in a separate group) from GROUP_INSNS, following
22809 one of the following schemes, depending on the value of the flag
22810 -minsert_sched_nops = X:
22811 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22812 in order to force NEXT_INSN into a separate group.
22813 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22814 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22815 insertion (has a group just ended, how many vacant issue slots remain in the
22816 last group, and how many dispatch groups were encountered so far). */
22819 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22820 rtx next_insn, bool *group_end, int can_issue_more,
22825 int issue_rate = rs6000_issue_rate ();
22826 bool end = *group_end;
22829 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22830 return can_issue_more;
22832 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22833 return can_issue_more;
22835 force = is_costly_group (group_insns, next_insn);
22837 return can_issue_more;
22839 if (sched_verbose > 6)
22840 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22841 *group_count ,can_issue_more);
22843 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22846 can_issue_more = 0;
22848 /* Since only a branch can be issued in the last issue_slot, it is
22849 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22850 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22851 in this case the last nop will start a new group and the branch
22852 will be forced to the new group. */
22853 if (can_issue_more && !is_branch_slot_insn (next_insn))
22856 while (can_issue_more > 0)
22859 emit_insn_before (nop, next_insn);
22867 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22869 int n_nops = rs6000_sched_insert_nops;
22871 /* Nops can't be issued from the branch slot, so the effective
22872 issue_rate for nops is 'issue_rate - 1'. */
22873 if (can_issue_more == 0)
22874 can_issue_more = issue_rate;
22876 if (can_issue_more == 0)
22878 can_issue_more = issue_rate - 1;
22881 for (i = 0; i < issue_rate; i++)
22883 group_insns[i] = 0;
22890 emit_insn_before (nop, next_insn);
22891 if (can_issue_more == issue_rate - 1) /* new group begins */
22894 if (can_issue_more == 0)
22896 can_issue_more = issue_rate - 1;
22899 for (i = 0; i < issue_rate; i++)
22901 group_insns[i] = 0;
22907 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22910 /* Is next_insn going to start a new group? */
22913 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22914 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22915 || (can_issue_more < issue_rate &&
22916 insn_terminates_group_p (next_insn, previous_group)));
22917 if (*group_end && end)
22920 if (sched_verbose > 6)
22921 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22922 *group_count, can_issue_more);
22923 return can_issue_more;
22926 return can_issue_more;
22929 /* This function tries to synch the dispatch groups that the compiler "sees"
22930 with the dispatch groups that the processor dispatcher is expected to
22931 form in practice. It tries to achieve this synchronization by forcing the
22932 estimated processor grouping on the compiler (as opposed to the function
22933 'pad_goups' which tries to force the scheduler's grouping on the processor).
22935 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22936 examines the (estimated) dispatch groups that will be formed by the processor
22937 dispatcher. It marks these group boundaries to reflect the estimated
22938 processor grouping, overriding the grouping that the scheduler had marked.
22939 Depending on the value of the flag '-minsert-sched-nops' this function can
22940 force certain insns into separate groups or force a certain distance between
22941 them by inserting nops, for example, if there exists a "costly dependence"
22944 The function estimates the group boundaries that the processor will form as
22945 follows: It keeps track of how many vacant issue slots are available after
22946 each insn. A subsequent insn will start a new group if one of the following
22948 - no more vacant issue slots remain in the current dispatch group.
22949 - only the last issue slot, which is the branch slot, is vacant, but the next
22950 insn is not a branch.
22951 - only the last 2 or less issue slots, including the branch slot, are vacant,
22952 which means that a cracked insn (which occupies two issue slots) can't be
22953 issued in this group.
22954 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22955 start a new group. */
22958 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22960 rtx insn, next_insn;
22962 int can_issue_more;
22965 int group_count = 0;
22969 issue_rate = rs6000_issue_rate ();
22970 group_insns = XALLOCAVEC (rtx, issue_rate);
22971 for (i = 0; i < issue_rate; i++)
22973 group_insns[i] = 0;
22975 can_issue_more = issue_rate;
22977 insn = get_next_active_insn (prev_head_insn, tail);
22980 while (insn != NULL_RTX)
22982 slot = (issue_rate - can_issue_more);
22983 group_insns[slot] = insn;
22985 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22986 if (insn_terminates_group_p (insn, current_group))
22987 can_issue_more = 0;
22989 next_insn = get_next_active_insn (insn, tail);
22990 if (next_insn == NULL_RTX)
22991 return group_count + 1;
22993 /* Is next_insn going to start a new group? */
22995 = (can_issue_more == 0
22996 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22997 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22998 || (can_issue_more < issue_rate &&
22999 insn_terminates_group_p (next_insn, previous_group)));
23001 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23002 next_insn, &group_end, can_issue_more,
23008 can_issue_more = 0;
23009 for (i = 0; i < issue_rate; i++)
23011 group_insns[i] = 0;
23015 if (GET_MODE (next_insn) == TImode && can_issue_more)
23016 PUT_MODE (next_insn, VOIDmode);
23017 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23018 PUT_MODE (next_insn, TImode);
23021 if (can_issue_more == 0)
23022 can_issue_more = issue_rate;
23025 return group_count;
23028 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23029 dispatch group boundaries that the scheduler had marked. Pad with nops
23030 any dispatch groups which have vacant issue slots, in order to force the
23031 scheduler's grouping on the processor dispatcher. The function
23032 returns the number of dispatch groups found. */
23035 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23037 rtx insn, next_insn;
23040 int can_issue_more;
23042 int group_count = 0;
23044 /* Initialize issue_rate. */
23045 issue_rate = rs6000_issue_rate ();
23046 can_issue_more = issue_rate;
23048 insn = get_next_active_insn (prev_head_insn, tail);
23049 next_insn = get_next_active_insn (insn, tail);
23051 while (insn != NULL_RTX)
23054 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23056 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23058 if (next_insn == NULL_RTX)
23063 /* If the scheduler had marked group termination at this location
23064 (between insn and next_insn), and neither insn nor next_insn will
23065 force group termination, pad the group with nops to force group
23068 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23069 && !insn_terminates_group_p (insn, current_group)
23070 && !insn_terminates_group_p (next_insn, previous_group))
23072 if (!is_branch_slot_insn (next_insn))
23075 while (can_issue_more)
23078 emit_insn_before (nop, next_insn);
23083 can_issue_more = issue_rate;
23088 next_insn = get_next_active_insn (insn, tail);
23091 return group_count;
23094 /* We're beginning a new block. Initialize data structures as necessary. */
23097 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23098 int sched_verbose ATTRIBUTE_UNUSED,
23099 int max_ready ATTRIBUTE_UNUSED)
23101 last_scheduled_insn = NULL_RTX;
23102 load_store_pendulum = 0;
23105 /* The following function is called at the end of scheduling BB.
23106 After reload, it inserts nops at insn group bundling. */
23109 rs6000_sched_finish (FILE *dump, int sched_verbose)
23114 fprintf (dump, "=== Finishing schedule.\n");
23116 if (reload_completed && rs6000_sched_groups)
23118 /* Do not run sched_finish hook when selective scheduling enabled. */
23119 if (sel_sched_p ())
23122 if (rs6000_sched_insert_nops == sched_finish_none)
23125 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23126 n_groups = pad_groups (dump, sched_verbose,
23127 current_sched_info->prev_head,
23128 current_sched_info->next_tail);
23130 n_groups = redefine_groups (dump, sched_verbose,
23131 current_sched_info->prev_head,
23132 current_sched_info->next_tail);
23134 if (sched_verbose >= 6)
23136 fprintf (dump, "ngroups = %d\n", n_groups);
23137 print_rtl (dump, current_sched_info->prev_head);
23138 fprintf (dump, "Done finish_sched\n");
23143 struct _rs6000_sched_context
23145 short cached_can_issue_more;
23146 rtx last_scheduled_insn;
23147 int load_store_pendulum;
23150 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23151 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23153 /* Allocate store for new scheduling context. */
23155 rs6000_alloc_sched_context (void)
23157 return xmalloc (sizeof (rs6000_sched_context_def));
23160 /* If CLEAN_P is true then initializes _SC with clean data,
23161 and from the global context otherwise. */
23163 rs6000_init_sched_context (void *_sc, bool clean_p)
23165 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23169 sc->cached_can_issue_more = 0;
23170 sc->last_scheduled_insn = NULL_RTX;
23171 sc->load_store_pendulum = 0;
23175 sc->cached_can_issue_more = cached_can_issue_more;
23176 sc->last_scheduled_insn = last_scheduled_insn;
23177 sc->load_store_pendulum = load_store_pendulum;
23181 /* Sets the global scheduling context to the one pointed to by _SC. */
23183 rs6000_set_sched_context (void *_sc)
23185 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23187 gcc_assert (sc != NULL);
23189 cached_can_issue_more = sc->cached_can_issue_more;
23190 last_scheduled_insn = sc->last_scheduled_insn;
23191 load_store_pendulum = sc->load_store_pendulum;
23196 rs6000_free_sched_context (void *_sc)
23198 gcc_assert (_sc != NULL);
23204 /* Length in units of the trampoline for entering a nested function. */
23207 rs6000_trampoline_size (void)
23211 switch (DEFAULT_ABI)
23214 gcc_unreachable ();
23217 ret = (TARGET_32BIT) ? 12 : 24;
23222 ret = (TARGET_32BIT) ? 40 : 48;
23229 /* Emit RTL insns to initialize the variable parts of a trampoline.
23230 FNADDR is an RTX for the address of the function's pure code.
23231 CXT is an RTX for the static chain value for the function. */
23234 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23236 int regsize = (TARGET_32BIT) ? 4 : 8;
23237 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23238 rtx ctx_reg = force_reg (Pmode, cxt);
23239 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23241 switch (DEFAULT_ABI)
23244 gcc_unreachable ();
23246 /* Under AIX, just build the 3 word function descriptor */
23249 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23250 rtx fn_reg = gen_reg_rtx (Pmode);
23251 rtx toc_reg = gen_reg_rtx (Pmode);
23253 /* Macro to shorten the code expansions below. */
23254 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23256 m_tramp = replace_equiv_address (m_tramp, addr);
23258 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23259 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23260 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23261 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23262 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23268 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23271 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23272 LCT_NORMAL, VOIDmode, 4,
23274 GEN_INT (rs6000_trampoline_size ()), SImode,
23282 /* Handle the "altivec" attribute. The attribute may have
23283 arguments as follows:
23285 __attribute__((altivec(vector__)))
23286 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23287 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23289 and may appear more than once (e.g., 'vector bool char') in a
23290 given declaration. */
23293 rs6000_handle_altivec_attribute (tree *node,
23294 tree name ATTRIBUTE_UNUSED,
23296 int flags ATTRIBUTE_UNUSED,
23297 bool *no_add_attrs)
23299 tree type = *node, result = NULL_TREE;
23300 enum machine_mode mode;
23303 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23304 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23305 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23308 while (POINTER_TYPE_P (type)
23309 || TREE_CODE (type) == FUNCTION_TYPE
23310 || TREE_CODE (type) == METHOD_TYPE
23311 || TREE_CODE (type) == ARRAY_TYPE)
23312 type = TREE_TYPE (type);
23314 mode = TYPE_MODE (type);
23316 /* Check for invalid AltiVec type qualifiers. */
23317 if (type == long_double_type_node)
23318 error ("use of %<long double%> in AltiVec types is invalid");
23319 else if (type == boolean_type_node)
23320 error ("use of boolean types in AltiVec types is invalid");
23321 else if (TREE_CODE (type) == COMPLEX_TYPE)
23322 error ("use of %<complex%> in AltiVec types is invalid");
23323 else if (DECIMAL_FLOAT_MODE_P (mode))
23324 error ("use of decimal floating point types in AltiVec types is invalid");
23325 else if (!TARGET_VSX)
23327 if (type == long_unsigned_type_node || type == long_integer_type_node)
23330 error ("use of %<long%> in AltiVec types is invalid for "
23331 "64-bit code without -mvsx");
23332 else if (rs6000_warn_altivec_long)
23333 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23336 else if (type == long_long_unsigned_type_node
23337 || type == long_long_integer_type_node)
23338 error ("use of %<long long%> in AltiVec types is invalid without "
23340 else if (type == double_type_node)
23341 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23344 switch (altivec_type)
23347 unsigned_p = TYPE_UNSIGNED (type);
23351 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23354 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23357 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23360 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23362 case SFmode: result = V4SF_type_node; break;
23363 case DFmode: result = V2DF_type_node; break;
23364 /* If the user says 'vector int bool', we may be handed the 'bool'
23365 attribute _before_ the 'vector' attribute, and so select the
23366 proper type in the 'b' case below. */
23367 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23368 case V2DImode: case V2DFmode:
23376 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23377 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23378 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23379 case QImode: case V16QImode: result = bool_V16QI_type_node;
23386 case V8HImode: result = pixel_V8HI_type_node;
23392 /* Propagate qualifiers attached to the element type
23393 onto the vector type. */
23394 if (result && result != type && TYPE_QUALS (type))
23395 result = build_qualified_type (result, TYPE_QUALS (type));
23397 *no_add_attrs = true; /* No need to hang on to the attribute. */
23400 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23405 /* AltiVec defines four built-in scalar types that serve as vector
23406 elements; we must teach the compiler how to mangle them. */
23408 static const char *
23409 rs6000_mangle_type (const_tree type)
23411 type = TYPE_MAIN_VARIANT (type);
23413 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23414 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23417 if (type == bool_char_type_node) return "U6__boolc";
23418 if (type == bool_short_type_node) return "U6__bools";
23419 if (type == pixel_type_node) return "u7__pixel";
23420 if (type == bool_int_type_node) return "U6__booli";
23421 if (type == bool_long_type_node) return "U6__booll";
23423 /* Mangle IBM extended float long double as `g' (__float128) on
23424 powerpc*-linux where long-double-64 previously was the default. */
23425 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23427 && TARGET_LONG_DOUBLE_128
23428 && !TARGET_IEEEQUAD)
23431 /* For all other types, use normal C++ mangling. */
23435 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23436 struct attribute_spec.handler. */
23439 rs6000_handle_longcall_attribute (tree *node, tree name,
23440 tree args ATTRIBUTE_UNUSED,
23441 int flags ATTRIBUTE_UNUSED,
23442 bool *no_add_attrs)
23444 if (TREE_CODE (*node) != FUNCTION_TYPE
23445 && TREE_CODE (*node) != FIELD_DECL
23446 && TREE_CODE (*node) != TYPE_DECL)
23448 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23450 *no_add_attrs = true;
23456 /* Set longcall attributes on all functions declared when
23457 rs6000_default_long_calls is true. */
23459 rs6000_set_default_type_attributes (tree type)
23461 if (rs6000_default_long_calls
23462 && (TREE_CODE (type) == FUNCTION_TYPE
23463 || TREE_CODE (type) == METHOD_TYPE))
23464 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23466 TYPE_ATTRIBUTES (type));
23469 darwin_set_default_type_attributes (type);
23473 /* Return a reference suitable for calling a function with the
23474 longcall attribute. */
23477 rs6000_longcall_ref (rtx call_ref)
23479 const char *call_name;
23482 if (GET_CODE (call_ref) != SYMBOL_REF)
23485 /* System V adds '.' to the internal name, so skip them. */
23486 call_name = XSTR (call_ref, 0);
23487 if (*call_name == '.')
23489 while (*call_name == '.')
23492 node = get_identifier (call_name);
23493 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23496 return force_reg (Pmode, call_ref);
23499 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23500 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23503 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23504 struct attribute_spec.handler. */
23506 rs6000_handle_struct_attribute (tree *node, tree name,
23507 tree args ATTRIBUTE_UNUSED,
23508 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23511 if (DECL_P (*node))
23513 if (TREE_CODE (*node) == TYPE_DECL)
23514 type = &TREE_TYPE (*node);
23519 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23520 || TREE_CODE (*type) == UNION_TYPE)))
23522 warning (OPT_Wattributes, "%qE attribute ignored", name);
23523 *no_add_attrs = true;
23526 else if ((is_attribute_p ("ms_struct", name)
23527 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23528 || ((is_attribute_p ("gcc_struct", name)
23529 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23531 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23533 *no_add_attrs = true;
23540 rs6000_ms_bitfield_layout_p (const_tree record_type)
23542 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23543 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23544 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23547 #ifdef USING_ELFOS_H
23549 /* A get_unnamed_section callback, used for switching to toc_section. */
23552 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23554 if (DEFAULT_ABI == ABI_AIX
23555 && TARGET_MINIMAL_TOC
23556 && !TARGET_RELOCATABLE)
23558 if (!toc_initialized)
23560 toc_initialized = 1;
23561 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23562 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23563 fprintf (asm_out_file, "\t.tc ");
23564 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23565 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23566 fprintf (asm_out_file, "\n");
23568 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23569 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23570 fprintf (asm_out_file, " = .+32768\n");
23573 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23575 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23576 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23579 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23580 if (!toc_initialized)
23582 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23583 fprintf (asm_out_file, " = .+32768\n");
23584 toc_initialized = 1;
23589 /* Implement TARGET_ASM_INIT_SECTIONS. */
23592 rs6000_elf_asm_init_sections (void)
23595 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23598 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23599 SDATA2_SECTION_ASM_OP);
23602 /* Implement TARGET_SELECT_RTX_SECTION. */
23605 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23606 unsigned HOST_WIDE_INT align)
23608 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23609 return toc_section;
23611 return default_elf_select_rtx_section (mode, x, align);
23614 /* For a SYMBOL_REF, set generic flags and then perform some
23615 target-specific processing.
23617 When the AIX ABI is requested on a non-AIX system, replace the
23618 function name with the real name (with a leading .) rather than the
23619 function descriptor name. This saves a lot of overriding code to
23620 read the prefixes. */
23623 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23625 default_encode_section_info (decl, rtl, first);
23628 && TREE_CODE (decl) == FUNCTION_DECL
23630 && DEFAULT_ABI == ABI_AIX)
23632 rtx sym_ref = XEXP (rtl, 0);
23633 size_t len = strlen (XSTR (sym_ref, 0));
23634 char *str = XALLOCAVEC (char, len + 2);
23636 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23637 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23642 compare_section_name (const char *section, const char *templ)
23646 len = strlen (templ);
23647 return (strncmp (section, templ, len) == 0
23648 && (section[len] == 0 || section[len] == '.'));
23652 rs6000_elf_in_small_data_p (const_tree decl)
23654 if (rs6000_sdata == SDATA_NONE)
23657 /* We want to merge strings, so we never consider them small data. */
23658 if (TREE_CODE (decl) == STRING_CST)
23661 /* Functions are never in the small data area. */
23662 if (TREE_CODE (decl) == FUNCTION_DECL)
23665 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23667 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23668 if (compare_section_name (section, ".sdata")
23669 || compare_section_name (section, ".sdata2")
23670 || compare_section_name (section, ".gnu.linkonce.s")
23671 || compare_section_name (section, ".sbss")
23672 || compare_section_name (section, ".sbss2")
23673 || compare_section_name (section, ".gnu.linkonce.sb")
23674 || strcmp (section, ".PPC.EMB.sdata0") == 0
23675 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23680 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23683 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23684 /* If it's not public, and we're not going to reference it there,
23685 there's no need to put it in the small data section. */
23686 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23693 #endif /* USING_ELFOS_H */
23695 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23698 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23700 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23703 /* Return a REG that occurs in ADDR with coefficient 1.
23704 ADDR can be effectively incremented by incrementing REG.
23706 r0 is special and we must not select it as an address
23707 register by this routine since our caller will try to
23708 increment the returned register via an "la" instruction. */
23711 find_addr_reg (rtx addr)
23713 while (GET_CODE (addr) == PLUS)
23715 if (GET_CODE (XEXP (addr, 0)) == REG
23716 && REGNO (XEXP (addr, 0)) != 0)
23717 addr = XEXP (addr, 0);
23718 else if (GET_CODE (XEXP (addr, 1)) == REG
23719 && REGNO (XEXP (addr, 1)) != 0)
23720 addr = XEXP (addr, 1);
23721 else if (CONSTANT_P (XEXP (addr, 0)))
23722 addr = XEXP (addr, 1);
23723 else if (CONSTANT_P (XEXP (addr, 1)))
23724 addr = XEXP (addr, 0);
23726 gcc_unreachable ();
23728 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23733 rs6000_fatal_bad_address (rtx op)
23735 fatal_insn ("bad address", op);
23740 static tree branch_island_list = 0;
23742 /* Remember to generate a branch island for far calls to the given
23746 add_compiler_branch_island (tree label_name, tree function_name,
23749 tree branch_island = build_tree_list (function_name, label_name);
23750 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23751 TREE_CHAIN (branch_island) = branch_island_list;
23752 branch_island_list = branch_island;
23755 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23756 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23757 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23758 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23760 /* Generate far-jump branch islands for everything on the
23761 branch_island_list. Invoked immediately after the last instruction
23762 of the epilogue has been emitted; the branch-islands must be
23763 appended to, and contiguous with, the function body. Mach-O stubs
23764 are generated in machopic_output_stub(). */
23767 macho_branch_islands (void)
23770 tree branch_island;
23772 for (branch_island = branch_island_list;
23774 branch_island = TREE_CHAIN (branch_island))
23776 const char *label =
23777 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23779 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23780 char name_buf[512];
23781 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23782 if (name[0] == '*' || name[0] == '&')
23783 strcpy (name_buf, name+1);
23787 strcpy (name_buf+1, name);
23789 strcpy (tmp_buf, "\n");
23790 strcat (tmp_buf, label);
23791 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23792 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23793 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23794 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23797 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23798 strcat (tmp_buf, label);
23799 strcat (tmp_buf, "_pic\n");
23800 strcat (tmp_buf, label);
23801 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23803 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23804 strcat (tmp_buf, name_buf);
23805 strcat (tmp_buf, " - ");
23806 strcat (tmp_buf, label);
23807 strcat (tmp_buf, "_pic)\n");
23809 strcat (tmp_buf, "\tmtlr r0\n");
23811 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23812 strcat (tmp_buf, name_buf);
23813 strcat (tmp_buf, " - ");
23814 strcat (tmp_buf, label);
23815 strcat (tmp_buf, "_pic)\n");
23817 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23821 strcat (tmp_buf, ":\nlis r12,hi16(");
23822 strcat (tmp_buf, name_buf);
23823 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23824 strcat (tmp_buf, name_buf);
23825 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23827 output_asm_insn (tmp_buf, 0);
23828 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23829 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23830 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23831 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23834 branch_island_list = 0;
23837 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23838 already there or not. */
23841 no_previous_def (tree function_name)
23843 tree branch_island;
23844 for (branch_island = branch_island_list;
23846 branch_island = TREE_CHAIN (branch_island))
23847 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23852 /* GET_PREV_LABEL gets the label name from the previous definition of
23856 get_prev_label (tree function_name)
23858 tree branch_island;
23859 for (branch_island = branch_island_list;
23861 branch_island = TREE_CHAIN (branch_island))
23862 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23863 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23867 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23868 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23871 /* KEXTs still need branch islands. */
23872 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23873 || flag_mkernel || flag_apple_kext)
23875 /* INSN is either a function call or a millicode call. It may have an
23876 unconditional jump in its delay slot.
23878 CALL_DEST is the routine we are calling. */
23881 output_call (rtx insn, rtx *operands, int dest_operand_number,
23882 int cookie_operand_number)
23884 static char buf[256];
23885 if (DARWIN_GENERATE_ISLANDS
23886 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23887 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23890 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23892 if (no_previous_def (funname))
23894 rtx label_rtx = gen_label_rtx ();
23895 char *label_buf, temp_buf[256];
23896 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23897 CODE_LABEL_NUMBER (label_rtx));
23898 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23899 labelname = get_identifier (label_buf);
23900 add_compiler_branch_island (labelname, funname, insn_line (insn));
23903 labelname = get_prev_label (funname);
23905 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23906 instruction will reach 'foo', otherwise link as 'bl L42'".
23907 "L42" should be a 'branch island', that will do a far jump to
23908 'foo'. Branch islands are generated in
23909 macho_branch_islands(). */
23910 sprintf (buf, "jbsr %%z%d,%.246s",
23911 dest_operand_number, IDENTIFIER_POINTER (labelname));
23914 sprintf (buf, "bl %%z%d", dest_operand_number);
23918 /* Generate PIC and indirect symbol stubs. */
23921 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23923 unsigned int length;
23924 char *symbol_name, *lazy_ptr_name;
23925 char *local_label_0;
23926 static int label = 0;
23928 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23929 symb = (*targetm.strip_name_encoding) (symb);
23932 length = strlen (symb);
23933 symbol_name = XALLOCAVEC (char, length + 32);
23934 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23936 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23937 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23940 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23942 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23946 fprintf (file, "\t.align 5\n");
23948 fprintf (file, "%s:\n", stub);
23949 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23952 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23953 sprintf (local_label_0, "\"L%011d$spb\"", label);
23955 fprintf (file, "\tmflr r0\n");
23956 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23957 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23958 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23959 lazy_ptr_name, local_label_0);
23960 fprintf (file, "\tmtlr r0\n");
23961 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23962 (TARGET_64BIT ? "ldu" : "lwzu"),
23963 lazy_ptr_name, local_label_0);
23964 fprintf (file, "\tmtctr r12\n");
23965 fprintf (file, "\tbctr\n");
23969 fprintf (file, "\t.align 4\n");
23971 fprintf (file, "%s:\n", stub);
23972 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23974 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23975 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23976 (TARGET_64BIT ? "ldu" : "lwzu"),
23978 fprintf (file, "\tmtctr r12\n");
23979 fprintf (file, "\tbctr\n");
23982 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23983 fprintf (file, "%s:\n", lazy_ptr_name);
23984 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23985 fprintf (file, "%sdyld_stub_binding_helper\n",
23986 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23989 /* Legitimize PIC addresses. If the address is already
23990 position-independent, we return ORIG. Newly generated
23991 position-independent addresses go into a reg. This is REG if non
23992 zero, otherwise we allocate register(s) as necessary. */
23994 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23997 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24002 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24003 reg = gen_reg_rtx (Pmode);
24005 if (GET_CODE (orig) == CONST)
24009 if (GET_CODE (XEXP (orig, 0)) == PLUS
24010 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24013 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24015 /* Use a different reg for the intermediate value, as
24016 it will be marked UNCHANGING. */
24017 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24018 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24021 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24024 if (GET_CODE (offset) == CONST_INT)
24026 if (SMALL_INT (offset))
24027 return plus_constant (base, INTVAL (offset));
24028 else if (! reload_in_progress && ! reload_completed)
24029 offset = force_reg (Pmode, offset);
24032 rtx mem = force_const_mem (Pmode, orig);
24033 return machopic_legitimize_pic_address (mem, Pmode, reg);
24036 return gen_rtx_PLUS (Pmode, base, offset);
24039 /* Fall back on generic machopic code. */
24040 return machopic_legitimize_pic_address (orig, mode, reg);
24043 /* Output a .machine directive for the Darwin assembler, and call
24044 the generic start_file routine. */
24047 rs6000_darwin_file_start (void)
24049 static const struct
24055 { "ppc64", "ppc64", MASK_64BIT },
24056 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24057 { "power4", "ppc970", 0 },
24058 { "G5", "ppc970", 0 },
24059 { "7450", "ppc7450", 0 },
24060 { "7400", "ppc7400", MASK_ALTIVEC },
24061 { "G4", "ppc7400", 0 },
24062 { "750", "ppc750", 0 },
24063 { "740", "ppc750", 0 },
24064 { "G3", "ppc750", 0 },
24065 { "604e", "ppc604e", 0 },
24066 { "604", "ppc604", 0 },
24067 { "603e", "ppc603", 0 },
24068 { "603", "ppc603", 0 },
24069 { "601", "ppc601", 0 },
24070 { NULL, "ppc", 0 } };
24071 const char *cpu_id = "";
24074 rs6000_file_start ();
24075 darwin_file_start ();
24077 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24078 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24079 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24080 && rs6000_select[i].string[0] != '\0')
24081 cpu_id = rs6000_select[i].string;
24083 /* Look through the mapping array. Pick the first name that either
24084 matches the argument, has a bit set in IF_SET that is also set
24085 in the target flags, or has a NULL name. */
24088 while (mapping[i].arg != NULL
24089 && strcmp (mapping[i].arg, cpu_id) != 0
24090 && (mapping[i].if_set & target_flags) == 0)
24093 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24096 #endif /* TARGET_MACHO */
24100 rs6000_elf_reloc_rw_mask (void)
24104 else if (DEFAULT_ABI == ABI_AIX)
24110 /* Record an element in the table of global constructors. SYMBOL is
24111 a SYMBOL_REF of the function to be called; PRIORITY is a number
24112 between 0 and MAX_INIT_PRIORITY.
24114 This differs from default_named_section_asm_out_constructor in
24115 that we have special handling for -mrelocatable. */
24118 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24120 const char *section = ".ctors";
24123 if (priority != DEFAULT_INIT_PRIORITY)
24125 sprintf (buf, ".ctors.%.5u",
24126 /* Invert the numbering so the linker puts us in the proper
24127 order; constructors are run from right to left, and the
24128 linker sorts in increasing order. */
24129 MAX_INIT_PRIORITY - priority);
24133 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24134 assemble_align (POINTER_SIZE);
24136 if (TARGET_RELOCATABLE)
24138 fputs ("\t.long (", asm_out_file);
24139 output_addr_const (asm_out_file, symbol);
24140 fputs (")@fixup\n", asm_out_file);
24143 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24147 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24149 const char *section = ".dtors";
24152 if (priority != DEFAULT_INIT_PRIORITY)
24154 sprintf (buf, ".dtors.%.5u",
24155 /* Invert the numbering so the linker puts us in the proper
24156 order; constructors are run from right to left, and the
24157 linker sorts in increasing order. */
24158 MAX_INIT_PRIORITY - priority);
24162 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24163 assemble_align (POINTER_SIZE);
24165 if (TARGET_RELOCATABLE)
24167 fputs ("\t.long (", asm_out_file);
24168 output_addr_const (asm_out_file, symbol);
24169 fputs (")@fixup\n", asm_out_file);
24172 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24176 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24180 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24181 ASM_OUTPUT_LABEL (file, name);
24182 fputs (DOUBLE_INT_ASM_OP, file);
24183 rs6000_output_function_entry (file, name);
24184 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24187 fputs ("\t.size\t", file);
24188 assemble_name (file, name);
24189 fputs (",24\n\t.type\t.", file);
24190 assemble_name (file, name);
24191 fputs (",@function\n", file);
24192 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24194 fputs ("\t.globl\t.", file);
24195 assemble_name (file, name);
24200 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24201 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24202 rs6000_output_function_entry (file, name);
24203 fputs (":\n", file);
24207 if (TARGET_RELOCATABLE
24208 && !TARGET_SECURE_PLT
24209 && (get_pool_size () != 0 || crtl->profile)
24214 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24216 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24217 fprintf (file, "\t.long ");
24218 assemble_name (file, buf);
24220 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24221 assemble_name (file, buf);
24225 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24226 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24228 if (DEFAULT_ABI == ABI_AIX)
24230 const char *desc_name, *orig_name;
24232 orig_name = (*targetm.strip_name_encoding) (name);
24233 desc_name = orig_name;
24234 while (*desc_name == '.')
24237 if (TREE_PUBLIC (decl))
24238 fprintf (file, "\t.globl %s\n", desc_name);
24240 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24241 fprintf (file, "%s:\n", desc_name);
24242 fprintf (file, "\t.long %s\n", orig_name);
24243 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24244 if (DEFAULT_ABI == ABI_AIX)
24245 fputs ("\t.long 0\n", file);
24246 fprintf (file, "\t.previous\n");
24248 ASM_OUTPUT_LABEL (file, name);
24252 rs6000_elf_end_indicate_exec_stack (void)
24255 file_end_indicate_exec_stack ();
24261 rs6000_xcoff_asm_output_anchor (rtx symbol)
24265 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24266 SYMBOL_REF_BLOCK_OFFSET (symbol));
24267 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24271 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24273 fputs (GLOBAL_ASM_OP, stream);
24274 RS6000_OUTPUT_BASENAME (stream, name);
24275 putc ('\n', stream);
24278 /* A get_unnamed_decl callback, used for read-only sections. PTR
24279 points to the section string variable. */
24282 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24284 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24285 *(const char *const *) directive,
24286 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24289 /* Likewise for read-write sections. */
24292 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24294 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24295 *(const char *const *) directive,
24296 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24299 /* A get_unnamed_section callback, used for switching to toc_section. */
24302 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24304 if (TARGET_MINIMAL_TOC)
24306 /* toc_section is always selected at least once from
24307 rs6000_xcoff_file_start, so this is guaranteed to
24308 always be defined once and only once in each file. */
24309 if (!toc_initialized)
24311 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24312 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24313 toc_initialized = 1;
24315 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24316 (TARGET_32BIT ? "" : ",3"));
24319 fputs ("\t.toc\n", asm_out_file);
24322 /* Implement TARGET_ASM_INIT_SECTIONS. */
24325 rs6000_xcoff_asm_init_sections (void)
24327 read_only_data_section
24328 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24329 &xcoff_read_only_section_name);
24331 private_data_section
24332 = get_unnamed_section (SECTION_WRITE,
24333 rs6000_xcoff_output_readwrite_section_asm_op,
24334 &xcoff_private_data_section_name);
24336 read_only_private_data_section
24337 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24338 &xcoff_private_data_section_name);
24341 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24343 readonly_data_section = read_only_data_section;
24344 exception_section = data_section;
24348 rs6000_xcoff_reloc_rw_mask (void)
24354 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24355 tree decl ATTRIBUTE_UNUSED)
24358 static const char * const suffix[3] = { "PR", "RO", "RW" };
24360 if (flags & SECTION_CODE)
24362 else if (flags & SECTION_WRITE)
24367 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24368 (flags & SECTION_CODE) ? "." : "",
24369 name, suffix[smclass], flags & SECTION_ENTSIZE);
24373 rs6000_xcoff_select_section (tree decl, int reloc,
24374 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24376 if (decl_readonly_section (decl, reloc))
24378 if (TREE_PUBLIC (decl))
24379 return read_only_data_section;
24381 return read_only_private_data_section;
24385 if (TREE_PUBLIC (decl))
24386 return data_section;
24388 return private_data_section;
24393 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24397 /* Use select_section for private and uninitialized data. */
24398 if (!TREE_PUBLIC (decl)
24399 || DECL_COMMON (decl)
24400 || DECL_INITIAL (decl) == NULL_TREE
24401 || DECL_INITIAL (decl) == error_mark_node
24402 || (flag_zero_initialized_in_bss
24403 && initializer_zerop (DECL_INITIAL (decl))))
24406 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24407 name = (*targetm.strip_name_encoding) (name);
24408 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24411 /* Select section for constant in constant pool.
24413 On RS/6000, all constants are in the private read-only data area.
24414 However, if this is being placed in the TOC it must be output as a
24418 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24419 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24421 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24422 return toc_section;
24424 return read_only_private_data_section;
24427 /* Remove any trailing [DS] or the like from the symbol name. */
24429 static const char *
24430 rs6000_xcoff_strip_name_encoding (const char *name)
24435 len = strlen (name);
24436 if (name[len - 1] == ']')
24437 return ggc_alloc_string (name, len - 4);
24442 /* Section attributes. AIX is always PIC. */
24444 static unsigned int
24445 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24447 unsigned int align;
24448 unsigned int flags = default_section_type_flags (decl, name, reloc);
24450 /* Align to at least UNIT size. */
24451 if (flags & SECTION_CODE)
24452 align = MIN_UNITS_PER_WORD;
24454 /* Increase alignment of large objects if not already stricter. */
24455 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24456 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24457 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24459 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24462 /* Output at beginning of assembler file.
24464 Initialize the section names for the RS/6000 at this point.
24466 Specify filename, including full path, to assembler.
24468 We want to go into the TOC section so at least one .toc will be emitted.
24469 Also, in order to output proper .bs/.es pairs, we need at least one static
24470 [RW] section emitted.
24472 Finally, declare mcount when profiling to make the assembler happy. */
24475 rs6000_xcoff_file_start (void)
24477 rs6000_gen_section_name (&xcoff_bss_section_name,
24478 main_input_filename, ".bss_");
24479 rs6000_gen_section_name (&xcoff_private_data_section_name,
24480 main_input_filename, ".rw_");
24481 rs6000_gen_section_name (&xcoff_read_only_section_name,
24482 main_input_filename, ".ro_");
24484 fputs ("\t.file\t", asm_out_file);
24485 output_quoted_string (asm_out_file, main_input_filename);
24486 fputc ('\n', asm_out_file);
24487 if (write_symbols != NO_DEBUG)
24488 switch_to_section (private_data_section);
24489 switch_to_section (text_section);
24491 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24492 rs6000_file_start ();
24495 /* Output at end of assembler file.
24496 On the RS/6000, referencing data should automatically pull in text. */
24499 rs6000_xcoff_file_end (void)
24501 switch_to_section (text_section);
24502 fputs ("_section_.text:\n", asm_out_file);
24503 switch_to_section (data_section);
24504 fputs (TARGET_32BIT
24505 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24508 #endif /* TARGET_XCOFF */
24510 /* Compute a (partial) cost for rtx X. Return true if the complete
24511 cost has been computed, and false if subexpressions should be
24512 scanned. In either case, *TOTAL contains the cost result. */
24515 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24518 enum machine_mode mode = GET_MODE (x);
24522 /* On the RS/6000, if it is valid in the insn, it is free. */
24524 if (((outer_code == SET
24525 || outer_code == PLUS
24526 || outer_code == MINUS)
24527 && (satisfies_constraint_I (x)
24528 || satisfies_constraint_L (x)))
24529 || (outer_code == AND
24530 && (satisfies_constraint_K (x)
24532 ? satisfies_constraint_L (x)
24533 : satisfies_constraint_J (x))
24534 || mask_operand (x, mode)
24536 && mask64_operand (x, DImode))))
24537 || ((outer_code == IOR || outer_code == XOR)
24538 && (satisfies_constraint_K (x)
24540 ? satisfies_constraint_L (x)
24541 : satisfies_constraint_J (x))))
24542 || outer_code == ASHIFT
24543 || outer_code == ASHIFTRT
24544 || outer_code == LSHIFTRT
24545 || outer_code == ROTATE
24546 || outer_code == ROTATERT
24547 || outer_code == ZERO_EXTRACT
24548 || (outer_code == MULT
24549 && satisfies_constraint_I (x))
24550 || ((outer_code == DIV || outer_code == UDIV
24551 || outer_code == MOD || outer_code == UMOD)
24552 && exact_log2 (INTVAL (x)) >= 0)
24553 || (outer_code == COMPARE
24554 && (satisfies_constraint_I (x)
24555 || satisfies_constraint_K (x)))
24556 || (outer_code == EQ
24557 && (satisfies_constraint_I (x)
24558 || satisfies_constraint_K (x)
24560 ? satisfies_constraint_L (x)
24561 : satisfies_constraint_J (x))))
24562 || (outer_code == GTU
24563 && satisfies_constraint_I (x))
24564 || (outer_code == LTU
24565 && satisfies_constraint_P (x)))
24570 else if ((outer_code == PLUS
24571 && reg_or_add_cint_operand (x, VOIDmode))
24572 || (outer_code == MINUS
24573 && reg_or_sub_cint_operand (x, VOIDmode))
24574 || ((outer_code == SET
24575 || outer_code == IOR
24576 || outer_code == XOR)
24578 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24580 *total = COSTS_N_INSNS (1);
24586 if (mode == DImode && code == CONST_DOUBLE)
24588 if ((outer_code == IOR || outer_code == XOR)
24589 && CONST_DOUBLE_HIGH (x) == 0
24590 && (CONST_DOUBLE_LOW (x)
24591 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24596 else if ((outer_code == AND && and64_2_operand (x, DImode))
24597 || ((outer_code == SET
24598 || outer_code == IOR
24599 || outer_code == XOR)
24600 && CONST_DOUBLE_HIGH (x) == 0))
24602 *total = COSTS_N_INSNS (1);
24612 /* When optimizing for size, MEM should be slightly more expensive
24613 than generating address, e.g., (plus (reg) (const)).
24614 L1 cache latency is about two instructions. */
24615 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24623 if (mode == DFmode)
24625 if (GET_CODE (XEXP (x, 0)) == MULT)
24627 /* FNMA accounted in outer NEG. */
24628 if (outer_code == NEG)
24629 *total = rs6000_cost->dmul - rs6000_cost->fp;
24631 *total = rs6000_cost->dmul;
24634 *total = rs6000_cost->fp;
24636 else if (mode == SFmode)
24638 /* FNMA accounted in outer NEG. */
24639 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24642 *total = rs6000_cost->fp;
24645 *total = COSTS_N_INSNS (1);
24649 if (mode == DFmode)
24651 if (GET_CODE (XEXP (x, 0)) == MULT
24652 || GET_CODE (XEXP (x, 1)) == MULT)
24654 /* FNMA accounted in outer NEG. */
24655 if (outer_code == NEG)
24656 *total = rs6000_cost->dmul - rs6000_cost->fp;
24658 *total = rs6000_cost->dmul;
24661 *total = rs6000_cost->fp;
24663 else if (mode == SFmode)
24665 /* FNMA accounted in outer NEG. */
24666 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24669 *total = rs6000_cost->fp;
24672 *total = COSTS_N_INSNS (1);
24676 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24677 && satisfies_constraint_I (XEXP (x, 1)))
24679 if (INTVAL (XEXP (x, 1)) >= -256
24680 && INTVAL (XEXP (x, 1)) <= 255)
24681 *total = rs6000_cost->mulsi_const9;
24683 *total = rs6000_cost->mulsi_const;
24685 /* FMA accounted in outer PLUS/MINUS. */
24686 else if ((mode == DFmode || mode == SFmode)
24687 && (outer_code == PLUS || outer_code == MINUS))
24689 else if (mode == DFmode)
24690 *total = rs6000_cost->dmul;
24691 else if (mode == SFmode)
24692 *total = rs6000_cost->fp;
24693 else if (mode == DImode)
24694 *total = rs6000_cost->muldi;
24696 *total = rs6000_cost->mulsi;
24701 if (FLOAT_MODE_P (mode))
24703 *total = mode == DFmode ? rs6000_cost->ddiv
24704 : rs6000_cost->sdiv;
24711 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24712 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24714 if (code == DIV || code == MOD)
24716 *total = COSTS_N_INSNS (2);
24719 *total = COSTS_N_INSNS (1);
24723 if (GET_MODE (XEXP (x, 1)) == DImode)
24724 *total = rs6000_cost->divdi;
24726 *total = rs6000_cost->divsi;
24728 /* Add in shift and subtract for MOD. */
24729 if (code == MOD || code == UMOD)
24730 *total += COSTS_N_INSNS (2);
24735 *total = COSTS_N_INSNS (4);
24739 *total = COSTS_N_INSNS (6);
24743 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24755 *total = COSTS_N_INSNS (1);
24763 /* Handle mul_highpart. */
24764 if (outer_code == TRUNCATE
24765 && GET_CODE (XEXP (x, 0)) == MULT)
24767 if (mode == DImode)
24768 *total = rs6000_cost->muldi;
24770 *total = rs6000_cost->mulsi;
24773 else if (outer_code == AND)
24776 *total = COSTS_N_INSNS (1);
24781 if (GET_CODE (XEXP (x, 0)) == MEM)
24784 *total = COSTS_N_INSNS (1);
24790 if (!FLOAT_MODE_P (mode))
24792 *total = COSTS_N_INSNS (1);
24798 case UNSIGNED_FLOAT:
24801 case FLOAT_TRUNCATE:
24802 *total = rs6000_cost->fp;
24806 if (mode == DFmode)
24809 *total = rs6000_cost->fp;
24813 switch (XINT (x, 1))
24816 *total = rs6000_cost->fp;
24828 *total = COSTS_N_INSNS (1);
24831 else if (FLOAT_MODE_P (mode)
24832 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24834 *total = rs6000_cost->fp;
24842 /* Carry bit requires mode == Pmode.
24843 NEG or PLUS already counted so only add one. */
24845 && (outer_code == NEG || outer_code == PLUS))
24847 *total = COSTS_N_INSNS (1);
24850 if (outer_code == SET)
24852 if (XEXP (x, 1) == const0_rtx)
24854 if (TARGET_ISEL && !TARGET_MFCRF)
24855 *total = COSTS_N_INSNS (8);
24857 *total = COSTS_N_INSNS (2);
24860 else if (mode == Pmode)
24862 *total = COSTS_N_INSNS (3);
24871 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24873 if (TARGET_ISEL && !TARGET_MFCRF)
24874 *total = COSTS_N_INSNS (8);
24876 *total = COSTS_N_INSNS (2);
24880 if (outer_code == COMPARE)
24894 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24897 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24900 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24903 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24904 "total = %d, speed = %s, x:\n",
24905 ret ? "complete" : "scan inner",
24906 GET_RTX_NAME (code),
24907 GET_RTX_NAME (outer_code),
24909 speed ? "true" : "false");
24916 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24919 rs6000_debug_address_cost (rtx x, bool speed)
24921 int ret = TARGET_ADDRESS_COST (x, speed);
24923 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24924 ret, speed ? "true" : "false");
24931 /* A C expression returning the cost of moving data from a register of class
24932 CLASS1 to one of CLASS2. */
24935 rs6000_register_move_cost (enum machine_mode mode,
24936 enum reg_class from, enum reg_class to)
24940 /* Moves from/to GENERAL_REGS. */
24941 if (reg_classes_intersect_p (to, GENERAL_REGS)
24942 || reg_classes_intersect_p (from, GENERAL_REGS))
24944 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24947 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24948 ret = (rs6000_memory_move_cost (mode, from, 0)
24949 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24951 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24953 else if (from == CR_REGS)
24956 /* Power6 has slower LR/CTR moves so make them more expensive than
24957 memory in order to bias spills to memory .*/
24958 else if (rs6000_cpu == PROCESSOR_POWER6
24959 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24960 ret = 6 * hard_regno_nregs[0][mode];
24963 /* A move will cost one instruction per GPR moved. */
24964 ret = 2 * hard_regno_nregs[0][mode];
24967 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24968 else if (VECTOR_UNIT_VSX_P (mode)
24969 && reg_classes_intersect_p (to, VSX_REGS)
24970 && reg_classes_intersect_p (from, VSX_REGS))
24971 ret = 2 * hard_regno_nregs[32][mode];
24973 /* Moving between two similar registers is just one instruction. */
24974 else if (reg_classes_intersect_p (to, from))
24975 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24977 /* Everything else has to go through GENERAL_REGS. */
24979 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24980 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24982 if (TARGET_DEBUG_COST)
24984 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24985 ret, GET_MODE_NAME (mode), reg_class_names[from],
24986 reg_class_names[to]);
24991 /* A C expressions returning the cost of moving data of MODE from a register to
24995 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24996 int in ATTRIBUTE_UNUSED)
25000 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25001 ret = 4 * hard_regno_nregs[0][mode];
25002 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25003 ret = 4 * hard_regno_nregs[32][mode];
25004 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25005 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25007 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25009 if (TARGET_DEBUG_COST)
25011 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25012 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25017 /* Returns a code for a target-specific builtin that implements
25018 reciprocal of the function, or NULL_TREE if not available. */
25021 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25022 bool sqrt ATTRIBUTE_UNUSED)
25024 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25025 && flag_finite_math_only && !flag_trapping_math
25026 && flag_unsafe_math_optimizations))
25034 case BUILT_IN_SQRTF:
25035 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25042 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25043 Assumes no trapping math and finite arguments. */
25046 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25048 rtx x0, e0, e1, y1, u0, v0, one;
25050 x0 = gen_reg_rtx (SFmode);
25051 e0 = gen_reg_rtx (SFmode);
25052 e1 = gen_reg_rtx (SFmode);
25053 y1 = gen_reg_rtx (SFmode);
25054 u0 = gen_reg_rtx (SFmode);
25055 v0 = gen_reg_rtx (SFmode);
25056 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25058 /* x0 = 1./d estimate */
25059 emit_insn (gen_rtx_SET (VOIDmode, x0,
25060 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25062 /* e0 = 1. - d * x0 */
25063 emit_insn (gen_rtx_SET (VOIDmode, e0,
25064 gen_rtx_MINUS (SFmode, one,
25065 gen_rtx_MULT (SFmode, d, x0))));
25066 /* e1 = e0 + e0 * e0 */
25067 emit_insn (gen_rtx_SET (VOIDmode, e1,
25068 gen_rtx_PLUS (SFmode,
25069 gen_rtx_MULT (SFmode, e0, e0), e0)));
25070 /* y1 = x0 + e1 * x0 */
25071 emit_insn (gen_rtx_SET (VOIDmode, y1,
25072 gen_rtx_PLUS (SFmode,
25073 gen_rtx_MULT (SFmode, e1, x0), x0)));
25075 emit_insn (gen_rtx_SET (VOIDmode, u0,
25076 gen_rtx_MULT (SFmode, n, y1)));
25077 /* v0 = n - d * u0 */
25078 emit_insn (gen_rtx_SET (VOIDmode, v0,
25079 gen_rtx_MINUS (SFmode, n,
25080 gen_rtx_MULT (SFmode, d, u0))));
25081 /* dst = u0 + v0 * y1 */
25082 emit_insn (gen_rtx_SET (VOIDmode, dst,
25083 gen_rtx_PLUS (SFmode,
25084 gen_rtx_MULT (SFmode, v0, y1), u0)));
25087 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25088 Assumes no trapping math and finite arguments. */
25091 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25093 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25095 x0 = gen_reg_rtx (DFmode);
25096 e0 = gen_reg_rtx (DFmode);
25097 e1 = gen_reg_rtx (DFmode);
25098 e2 = gen_reg_rtx (DFmode);
25099 y1 = gen_reg_rtx (DFmode);
25100 y2 = gen_reg_rtx (DFmode);
25101 y3 = gen_reg_rtx (DFmode);
25102 u0 = gen_reg_rtx (DFmode);
25103 v0 = gen_reg_rtx (DFmode);
25104 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25106 /* x0 = 1./d estimate */
25107 emit_insn (gen_rtx_SET (VOIDmode, x0,
25108 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25110 /* e0 = 1. - d * x0 */
25111 emit_insn (gen_rtx_SET (VOIDmode, e0,
25112 gen_rtx_MINUS (DFmode, one,
25113 gen_rtx_MULT (SFmode, d, x0))));
25114 /* y1 = x0 + e0 * x0 */
25115 emit_insn (gen_rtx_SET (VOIDmode, y1,
25116 gen_rtx_PLUS (DFmode,
25117 gen_rtx_MULT (DFmode, e0, x0), x0)));
25119 emit_insn (gen_rtx_SET (VOIDmode, e1,
25120 gen_rtx_MULT (DFmode, e0, e0)));
25121 /* y2 = y1 + e1 * y1 */
25122 emit_insn (gen_rtx_SET (VOIDmode, y2,
25123 gen_rtx_PLUS (DFmode,
25124 gen_rtx_MULT (DFmode, e1, y1), y1)));
25126 emit_insn (gen_rtx_SET (VOIDmode, e2,
25127 gen_rtx_MULT (DFmode, e1, e1)));
25128 /* y3 = y2 + e2 * y2 */
25129 emit_insn (gen_rtx_SET (VOIDmode, y3,
25130 gen_rtx_PLUS (DFmode,
25131 gen_rtx_MULT (DFmode, e2, y2), y2)));
25133 emit_insn (gen_rtx_SET (VOIDmode, u0,
25134 gen_rtx_MULT (DFmode, n, y3)));
25135 /* v0 = n - d * u0 */
25136 emit_insn (gen_rtx_SET (VOIDmode, v0,
25137 gen_rtx_MINUS (DFmode, n,
25138 gen_rtx_MULT (DFmode, d, u0))));
25139 /* dst = u0 + v0 * y3 */
25140 emit_insn (gen_rtx_SET (VOIDmode, dst,
25141 gen_rtx_PLUS (DFmode,
25142 gen_rtx_MULT (DFmode, v0, y3), u0)));
25146 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25147 Assumes no trapping math and finite arguments. */
25150 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25152 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25153 half, one, halfthree, c1, cond, label;
25155 x0 = gen_reg_rtx (SFmode);
25156 x1 = gen_reg_rtx (SFmode);
25157 x2 = gen_reg_rtx (SFmode);
25158 y1 = gen_reg_rtx (SFmode);
25159 u0 = gen_reg_rtx (SFmode);
25160 u1 = gen_reg_rtx (SFmode);
25161 u2 = gen_reg_rtx (SFmode);
25162 v0 = gen_reg_rtx (SFmode);
25163 v1 = gen_reg_rtx (SFmode);
25164 v2 = gen_reg_rtx (SFmode);
25165 t0 = gen_reg_rtx (SFmode);
25166 halfthree = gen_reg_rtx (SFmode);
25167 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25168 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25170 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25171 emit_insn (gen_rtx_SET (VOIDmode, t0,
25172 gen_rtx_MULT (SFmode, src, src)));
25174 emit_insn (gen_rtx_SET (VOIDmode, cond,
25175 gen_rtx_COMPARE (CCFPmode, t0, src)));
25176 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25177 emit_unlikely_jump (c1, label);
25179 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25180 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25182 /* halfthree = 1.5 = 1.0 + 0.5 */
25183 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25184 gen_rtx_PLUS (SFmode, one, half)));
25186 /* x0 = rsqrt estimate */
25187 emit_insn (gen_rtx_SET (VOIDmode, x0,
25188 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25191 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25192 emit_insn (gen_rtx_SET (VOIDmode, y1,
25193 gen_rtx_MINUS (SFmode,
25194 gen_rtx_MULT (SFmode, src, halfthree),
25197 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25198 emit_insn (gen_rtx_SET (VOIDmode, u0,
25199 gen_rtx_MULT (SFmode, x0, x0)));
25200 emit_insn (gen_rtx_SET (VOIDmode, v0,
25201 gen_rtx_MINUS (SFmode,
25203 gen_rtx_MULT (SFmode, y1, u0))));
25204 emit_insn (gen_rtx_SET (VOIDmode, x1,
25205 gen_rtx_MULT (SFmode, x0, v0)));
25207 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25208 emit_insn (gen_rtx_SET (VOIDmode, u1,
25209 gen_rtx_MULT (SFmode, x1, x1)));
25210 emit_insn (gen_rtx_SET (VOIDmode, v1,
25211 gen_rtx_MINUS (SFmode,
25213 gen_rtx_MULT (SFmode, y1, u1))));
25214 emit_insn (gen_rtx_SET (VOIDmode, x2,
25215 gen_rtx_MULT (SFmode, x1, v1)));
25217 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25218 emit_insn (gen_rtx_SET (VOIDmode, u2,
25219 gen_rtx_MULT (SFmode, x2, x2)));
25220 emit_insn (gen_rtx_SET (VOIDmode, v2,
25221 gen_rtx_MINUS (SFmode,
25223 gen_rtx_MULT (SFmode, y1, u2))));
25224 emit_insn (gen_rtx_SET (VOIDmode, dst,
25225 gen_rtx_MULT (SFmode, x2, v2)));
25227 emit_label (XEXP (label, 0));
25230 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25231 (Power7) targets. DST is the target, and SRC is the argument operand. */
25234 rs6000_emit_popcount (rtx dst, rtx src)
25236 enum machine_mode mode = GET_MODE (dst);
25239 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25240 if (TARGET_POPCNTD)
25242 if (mode == SImode)
25243 emit_insn (gen_popcntwsi2 (dst, src));
25245 emit_insn (gen_popcntddi2 (dst, src));
25249 tmp1 = gen_reg_rtx (mode);
25251 if (mode == SImode)
25253 emit_insn (gen_popcntbsi2 (tmp1, src));
25254 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25256 tmp2 = force_reg (SImode, tmp2);
25257 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25261 emit_insn (gen_popcntbdi2 (tmp1, src));
25262 tmp2 = expand_mult (DImode, tmp1,
25263 GEN_INT ((HOST_WIDE_INT)
25264 0x01010101 << 32 | 0x01010101),
25266 tmp2 = force_reg (DImode, tmp2);
25267 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25272 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25273 target, and SRC is the argument operand. */
25276 rs6000_emit_parity (rtx dst, rtx src)
25278 enum machine_mode mode = GET_MODE (dst);
25281 tmp = gen_reg_rtx (mode);
25282 if (mode == SImode)
25284 /* Is mult+shift >= shift+xor+shift+xor? */
25285 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25287 rtx tmp1, tmp2, tmp3, tmp4;
25289 tmp1 = gen_reg_rtx (SImode);
25290 emit_insn (gen_popcntbsi2 (tmp1, src));
25292 tmp2 = gen_reg_rtx (SImode);
25293 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25294 tmp3 = gen_reg_rtx (SImode);
25295 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25297 tmp4 = gen_reg_rtx (SImode);
25298 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25299 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25302 rs6000_emit_popcount (tmp, src);
25303 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25307 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25308 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25310 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25312 tmp1 = gen_reg_rtx (DImode);
25313 emit_insn (gen_popcntbdi2 (tmp1, src));
25315 tmp2 = gen_reg_rtx (DImode);
25316 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25317 tmp3 = gen_reg_rtx (DImode);
25318 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25320 tmp4 = gen_reg_rtx (DImode);
25321 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25322 tmp5 = gen_reg_rtx (DImode);
25323 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25325 tmp6 = gen_reg_rtx (DImode);
25326 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25327 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25330 rs6000_emit_popcount (tmp, src);
25331 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25335 /* Return an RTX representing where to find the function value of a
25336 function returning MODE. */
25338 rs6000_complex_function_value (enum machine_mode mode)
25340 unsigned int regno;
25342 enum machine_mode inner = GET_MODE_INNER (mode);
25343 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25345 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25346 regno = FP_ARG_RETURN;
25349 regno = GP_ARG_RETURN;
25351 /* 32-bit is OK since it'll go in r3/r4. */
25352 if (TARGET_32BIT && inner_bytes >= 4)
25353 return gen_rtx_REG (mode, regno);
25356 if (inner_bytes >= 8)
25357 return gen_rtx_REG (mode, regno);
25359 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25361 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25362 GEN_INT (inner_bytes));
25363 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25366 /* Target hook for TARGET_FUNCTION_VALUE.
25368 On the SPE, both FPs and vectors are returned in r3.
25370 On RS/6000 an integer value is in r3 and a floating-point value is in
25371 fp1, unless -msoft-float. */
25374 rs6000_function_value (const_tree valtype,
25375 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25376 bool outgoing ATTRIBUTE_UNUSED)
25378 enum machine_mode mode;
25379 unsigned int regno;
25381 /* Special handling for structs in darwin64. */
25382 if (rs6000_darwin64_abi
25383 && TYPE_MODE (valtype) == BLKmode
25384 && TREE_CODE (valtype) == RECORD_TYPE
25385 && int_size_in_bytes (valtype) > 0)
25387 CUMULATIVE_ARGS valcum;
25391 valcum.fregno = FP_ARG_MIN_REG;
25392 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25393 /* Do a trial code generation as if this were going to be passed as
25394 an argument; if any part goes in memory, we return NULL. */
25395 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25398 /* Otherwise fall through to standard ABI rules. */
25401 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25403 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25404 return gen_rtx_PARALLEL (DImode,
25406 gen_rtx_EXPR_LIST (VOIDmode,
25407 gen_rtx_REG (SImode, GP_ARG_RETURN),
25409 gen_rtx_EXPR_LIST (VOIDmode,
25410 gen_rtx_REG (SImode,
25411 GP_ARG_RETURN + 1),
25414 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25416 return gen_rtx_PARALLEL (DCmode,
25418 gen_rtx_EXPR_LIST (VOIDmode,
25419 gen_rtx_REG (SImode, GP_ARG_RETURN),
25421 gen_rtx_EXPR_LIST (VOIDmode,
25422 gen_rtx_REG (SImode,
25423 GP_ARG_RETURN + 1),
25425 gen_rtx_EXPR_LIST (VOIDmode,
25426 gen_rtx_REG (SImode,
25427 GP_ARG_RETURN + 2),
25429 gen_rtx_EXPR_LIST (VOIDmode,
25430 gen_rtx_REG (SImode,
25431 GP_ARG_RETURN + 3),
25435 mode = TYPE_MODE (valtype);
25436 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25437 || POINTER_TYPE_P (valtype))
25438 mode = TARGET_32BIT ? SImode : DImode;
25440 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25441 /* _Decimal128 must use an even/odd register pair. */
25442 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25443 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25444 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25445 regno = FP_ARG_RETURN;
25446 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25447 && targetm.calls.split_complex_arg)
25448 return rs6000_complex_function_value (mode);
25449 else if (TREE_CODE (valtype) == VECTOR_TYPE
25450 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25451 && ALTIVEC_VECTOR_MODE (mode))
25452 regno = ALTIVEC_ARG_RETURN;
25453 else if (TREE_CODE (valtype) == VECTOR_TYPE
25454 && TARGET_VSX && TARGET_ALTIVEC_ABI
25455 && VSX_VECTOR_MODE (mode))
25456 regno = ALTIVEC_ARG_RETURN;
25457 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25458 && (mode == DFmode || mode == DCmode
25459 || mode == TFmode || mode == TCmode))
25460 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25462 regno = GP_ARG_RETURN;
25464 return gen_rtx_REG (mode, regno);
25467 /* Define how to find the value returned by a library function
25468 assuming the value has mode MODE. */
25470 rs6000_libcall_value (enum machine_mode mode)
25472 unsigned int regno;
25474 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25476 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25477 return gen_rtx_PARALLEL (DImode,
25479 gen_rtx_EXPR_LIST (VOIDmode,
25480 gen_rtx_REG (SImode, GP_ARG_RETURN),
25482 gen_rtx_EXPR_LIST (VOIDmode,
25483 gen_rtx_REG (SImode,
25484 GP_ARG_RETURN + 1),
25488 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25489 /* _Decimal128 must use an even/odd register pair. */
25490 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25491 else if (SCALAR_FLOAT_MODE_P (mode)
25492 && TARGET_HARD_FLOAT && TARGET_FPRS
25493 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25494 regno = FP_ARG_RETURN;
25495 else if (ALTIVEC_VECTOR_MODE (mode)
25496 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25497 regno = ALTIVEC_ARG_RETURN;
25498 else if (VSX_VECTOR_MODE (mode)
25499 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25500 regno = ALTIVEC_ARG_RETURN;
25501 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25502 return rs6000_complex_function_value (mode);
25503 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25504 && (mode == DFmode || mode == DCmode
25505 || mode == TFmode || mode == TCmode))
25506 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25508 regno = GP_ARG_RETURN;
25510 return gen_rtx_REG (mode, regno);
25514 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25515 Frame pointer elimination is automatically handled.
25517 For the RS/6000, if frame pointer elimination is being done, we would like
25518 to convert ap into fp, not sp.
25520 We need r30 if -mminimal-toc was specified, and there are constant pool
25524 rs6000_can_eliminate (const int from, const int to)
25526 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25527 ? ! frame_pointer_needed
25528 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25529 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25533 /* Define the offset between two registers, FROM to be eliminated and its
25534 replacement TO, at the start of a routine. */
25536 rs6000_initial_elimination_offset (int from, int to)
25538 rs6000_stack_t *info = rs6000_stack_info ();
25539 HOST_WIDE_INT offset;
25541 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25542 offset = info->push_p ? 0 : -info->total_size;
25543 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25545 offset = info->push_p ? 0 : -info->total_size;
25546 if (FRAME_GROWS_DOWNWARD)
25547 offset += info->fixed_size + info->vars_size + info->parm_size;
25549 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25550 offset = FRAME_GROWS_DOWNWARD
25551 ? info->fixed_size + info->vars_size + info->parm_size
25553 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25554 offset = info->total_size;
25555 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25556 offset = info->push_p ? info->total_size : 0;
25557 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25560 gcc_unreachable ();
25566 rs6000_dwarf_register_span (rtx reg)
25570 unsigned regno = REGNO (reg);
25571 enum machine_mode mode = GET_MODE (reg);
25575 && (SPE_VECTOR_MODE (GET_MODE (reg))
25576 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25577 && mode != SFmode && mode != SDmode && mode != SCmode)))
25582 regno = REGNO (reg);
25584 /* The duality of the SPE register size wreaks all kinds of havoc.
25585 This is a way of distinguishing r0 in 32-bits from r0 in
25587 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25588 gcc_assert (words <= 4);
25589 for (i = 0; i < words; i++, regno++)
25591 if (BYTES_BIG_ENDIAN)
25593 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25594 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25598 parts[2 * i] = gen_rtx_REG (SImode, regno);
25599 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25603 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25606 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25609 rs6000_init_dwarf_reg_sizes_extra (tree address)
25614 enum machine_mode mode = TYPE_MODE (char_type_node);
25615 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25616 rtx mem = gen_rtx_MEM (BLKmode, addr);
25617 rtx value = gen_int_mode (4, mode);
25619 for (i = 1201; i < 1232; i++)
25621 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25622 HOST_WIDE_INT offset
25623 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25625 emit_move_insn (adjust_address (mem, mode, offset), value);
25630 /* Map internal gcc register numbers to DWARF2 register numbers. */
25633 rs6000_dbx_register_number (unsigned int regno)
25635 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25637 if (regno == MQ_REGNO)
25639 if (regno == LR_REGNO)
25641 if (regno == CTR_REGNO)
25643 if (CR_REGNO_P (regno))
25644 return regno - CR0_REGNO + 86;
25645 if (regno == XER_REGNO)
25647 if (ALTIVEC_REGNO_P (regno))
25648 return regno - FIRST_ALTIVEC_REGNO + 1124;
25649 if (regno == VRSAVE_REGNO)
25651 if (regno == VSCR_REGNO)
25653 if (regno == SPE_ACC_REGNO)
25655 if (regno == SPEFSCR_REGNO)
25657 /* SPE high reg number. We get these values of regno from
25658 rs6000_dwarf_register_span. */
25659 gcc_assert (regno >= 1200 && regno < 1232);
25663 /* target hook eh_return_filter_mode */
25664 static enum machine_mode
25665 rs6000_eh_return_filter_mode (void)
25667 return TARGET_32BIT ? SImode : word_mode;
25670 /* Target hook for scalar_mode_supported_p. */
25672 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25674 if (DECIMAL_FLOAT_MODE_P (mode))
25675 return default_decimal_float_supported_p ();
25677 return default_scalar_mode_supported_p (mode);
25680 /* Target hook for vector_mode_supported_p. */
25682 rs6000_vector_mode_supported_p (enum machine_mode mode)
25685 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25688 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25691 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25698 /* Target hook for invalid_arg_for_unprototyped_fn. */
25699 static const char *
25700 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25702 return (!rs6000_darwin64_abi
25704 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25705 && (funcdecl == NULL_TREE
25706 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25707 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25708 ? N_("AltiVec argument passed to unprototyped function")
25712 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25713 setup by using __stack_chk_fail_local hidden function instead of
25714 calling __stack_chk_fail directly. Otherwise it is better to call
25715 __stack_chk_fail directly. */
25718 rs6000_stack_protect_fail (void)
25720 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25721 ? default_hidden_stack_protect_fail ()
25722 : default_external_stack_protect_fail ();
25726 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25727 int num_operands ATTRIBUTE_UNUSED)
25729 if (rs6000_warn_cell_microcode)
25732 int insn_code_number = recog_memoized (insn);
25733 location_t location = locator_location (INSN_LOCATOR (insn));
25735 /* Punt on insns we cannot recognize. */
25736 if (insn_code_number < 0)
25739 temp = get_insn_template (insn_code_number, insn);
25741 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25742 warning_at (location, OPT_mwarn_cell_microcode,
25743 "emitting microcode insn %s\t[%s] #%d",
25744 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25745 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25746 warning_at (location, OPT_mwarn_cell_microcode,
25747 "emitting conditional microcode insn %s\t[%s] #%d",
25748 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25752 #include "gt-rs6000.h"