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
1274 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1275 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1277 /* Initialize the GCC target structure. */
1278 #undef TARGET_ATTRIBUTE_TABLE
1279 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1280 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1281 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1283 #undef TARGET_ASM_ALIGNED_DI_OP
1284 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1286 /* Default unaligned ops are only provided for ELF. Find the ops needed
1287 for non-ELF systems. */
1288 #ifndef OBJECT_FORMAT_ELF
1290 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1292 #undef TARGET_ASM_UNALIGNED_HI_OP
1293 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1294 #undef TARGET_ASM_UNALIGNED_SI_OP
1295 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1296 #undef TARGET_ASM_UNALIGNED_DI_OP
1297 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1300 #undef TARGET_ASM_UNALIGNED_HI_OP
1301 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1302 #undef TARGET_ASM_UNALIGNED_SI_OP
1303 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1304 #undef TARGET_ASM_UNALIGNED_DI_OP
1305 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1306 #undef TARGET_ASM_ALIGNED_DI_OP
1307 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1311 /* This hook deals with fixups for relocatable code and DI-mode objects
1313 #undef TARGET_ASM_INTEGER
1314 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1316 #ifdef HAVE_GAS_HIDDEN
1317 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1318 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1321 #undef TARGET_HAVE_TLS
1322 #define TARGET_HAVE_TLS HAVE_AS_TLS
1324 #undef TARGET_CANNOT_FORCE_CONST_MEM
1325 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1327 #undef TARGET_DELEGITIMIZE_ADDRESS
1328 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1330 #undef TARGET_ASM_FUNCTION_PROLOGUE
1331 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1332 #undef TARGET_ASM_FUNCTION_EPILOGUE
1333 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1335 #undef TARGET_LEGITIMIZE_ADDRESS
1336 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1338 #undef TARGET_SCHED_VARIABLE_ISSUE
1339 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1341 #undef TARGET_SCHED_ISSUE_RATE
1342 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1343 #undef TARGET_SCHED_ADJUST_COST
1344 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1345 #undef TARGET_SCHED_ADJUST_PRIORITY
1346 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1347 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1348 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1349 #undef TARGET_SCHED_INIT
1350 #define TARGET_SCHED_INIT rs6000_sched_init
1351 #undef TARGET_SCHED_FINISH
1352 #define TARGET_SCHED_FINISH rs6000_sched_finish
1353 #undef TARGET_SCHED_REORDER
1354 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1355 #undef TARGET_SCHED_REORDER2
1356 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1358 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1359 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1361 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1362 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1364 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1365 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1366 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1367 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1368 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1369 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1370 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1371 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1373 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1374 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1375 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1376 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1377 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1378 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1379 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1380 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1381 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1382 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1383 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1384 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1385 rs6000_builtin_support_vector_misalignment
1386 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1387 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1389 #undef TARGET_INIT_BUILTINS
1390 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1391 #undef TARGET_BUILTIN_DECL
1392 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1394 #undef TARGET_EXPAND_BUILTIN
1395 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1397 #undef TARGET_MANGLE_TYPE
1398 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1400 #undef TARGET_INIT_LIBFUNCS
1401 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1404 #undef TARGET_BINDS_LOCAL_P
1405 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1408 #undef TARGET_MS_BITFIELD_LAYOUT_P
1409 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1411 #undef TARGET_ASM_OUTPUT_MI_THUNK
1412 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1414 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1415 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1417 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1418 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1420 #undef TARGET_INVALID_WITHIN_DOLOOP
1421 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1423 #undef TARGET_RTX_COSTS
1424 #define TARGET_RTX_COSTS rs6000_rtx_costs
1425 #undef TARGET_ADDRESS_COST
1426 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1428 #undef TARGET_DWARF_REGISTER_SPAN
1429 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1431 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1432 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1434 /* On rs6000, function arguments are promoted, as are function return
1436 #undef TARGET_PROMOTE_FUNCTION_MODE
1437 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1439 #undef TARGET_RETURN_IN_MEMORY
1440 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1442 #undef TARGET_SETUP_INCOMING_VARARGS
1443 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1445 /* Always strict argument naming on rs6000. */
1446 #undef TARGET_STRICT_ARGUMENT_NAMING
1447 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1448 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1449 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1450 #undef TARGET_SPLIT_COMPLEX_ARG
1451 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1452 #undef TARGET_MUST_PASS_IN_STACK
1453 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1454 #undef TARGET_PASS_BY_REFERENCE
1455 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1456 #undef TARGET_ARG_PARTIAL_BYTES
1457 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1459 #undef TARGET_BUILD_BUILTIN_VA_LIST
1460 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1462 #undef TARGET_EXPAND_BUILTIN_VA_START
1463 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1465 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1466 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1468 #undef TARGET_EH_RETURN_FILTER_MODE
1469 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1471 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1472 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1474 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1475 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1477 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1478 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1480 #undef TARGET_HANDLE_OPTION
1481 #define TARGET_HANDLE_OPTION rs6000_handle_option
1483 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1484 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1485 rs6000_builtin_vectorized_function
1487 #undef TARGET_DEFAULT_TARGET_FLAGS
1488 #define TARGET_DEFAULT_TARGET_FLAGS \
1491 #undef TARGET_STACK_PROTECT_FAIL
1492 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1494 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1495 The PowerPC architecture requires only weak consistency among
1496 processors--that is, memory accesses between processors need not be
1497 sequentially consistent and memory accesses among processors can occur
1498 in any order. The ability to order memory accesses weakly provides
1499 opportunities for more efficient use of the system bus. Unless a
1500 dependency exists, the 604e allows read operations to precede store
1502 #undef TARGET_RELAXED_ORDERING
1503 #define TARGET_RELAXED_ORDERING true
1506 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1507 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1510 /* Use a 32-bit anchor range. This leads to sequences like:
1512 addis tmp,anchor,high
1515 where tmp itself acts as an anchor, and can be shared between
1516 accesses to the same 64k page. */
1517 #undef TARGET_MIN_ANCHOR_OFFSET
1518 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1519 #undef TARGET_MAX_ANCHOR_OFFSET
1520 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1521 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1522 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1524 #undef TARGET_BUILTIN_RECIPROCAL
1525 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1527 #undef TARGET_EXPAND_TO_RTL_HOOK
1528 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1530 #undef TARGET_INSTANTIATE_DECLS
1531 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1533 #undef TARGET_SECONDARY_RELOAD
1534 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1536 #undef TARGET_IRA_COVER_CLASSES
1537 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1539 #undef TARGET_LEGITIMATE_ADDRESS_P
1540 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1542 #undef TARGET_CAN_ELIMINATE
1543 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1545 #undef TARGET_TRAMPOLINE_INIT
1546 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1548 #undef TARGET_FUNCTION_VALUE
1549 #define TARGET_FUNCTION_VALUE rs6000_function_value
1551 struct gcc_target targetm = TARGET_INITIALIZER;
1553 /* Return number of consecutive hard regs needed starting at reg REGNO
1554 to hold something of mode MODE.
1555 This is ordinarily the length in words of a value of mode MODE
1556 but can be less for certain modes in special long registers.
1558 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1559 scalar instructions. The upper 32 bits are only available to the
1562 POWER and PowerPC GPRs hold 32 bits worth;
1563 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1566 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1568 unsigned HOST_WIDE_INT reg_size;
1570 if (FP_REGNO_P (regno))
1571 reg_size = (VECTOR_MEM_VSX_P (mode)
1572 ? UNITS_PER_VSX_WORD
1573 : UNITS_PER_FP_WORD);
1575 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1576 reg_size = UNITS_PER_SPE_WORD;
1578 else if (ALTIVEC_REGNO_P (regno))
1579 reg_size = UNITS_PER_ALTIVEC_WORD;
1581 /* The value returned for SCmode in the E500 double case is 2 for
1582 ABI compatibility; storing an SCmode value in a single register
1583 would require function_arg and rs6000_spe_function_arg to handle
1584 SCmode so as to pass the value correctly in a pair of
1586 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1587 && !DECIMAL_FLOAT_MODE_P (mode))
1588 reg_size = UNITS_PER_FP_WORD;
1591 reg_size = UNITS_PER_WORD;
1593 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1596 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1599 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1601 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1603 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1604 implementations. Don't allow an item to be split between a FP register
1605 and an Altivec register. */
1606 if (VECTOR_MEM_VSX_P (mode))
1608 if (FP_REGNO_P (regno))
1609 return FP_REGNO_P (last_regno);
1611 if (ALTIVEC_REGNO_P (regno))
1612 return ALTIVEC_REGNO_P (last_regno);
1615 /* The GPRs can hold any mode, but values bigger than one register
1616 cannot go past R31. */
1617 if (INT_REGNO_P (regno))
1618 return INT_REGNO_P (last_regno);
1620 /* The float registers (except for VSX vector modes) can only hold floating
1621 modes and DImode. This excludes the 32-bit decimal float mode for
1623 if (FP_REGNO_P (regno))
1625 if (SCALAR_FLOAT_MODE_P (mode)
1626 && (mode != TDmode || (regno % 2) == 0)
1627 && FP_REGNO_P (last_regno))
1630 if (GET_MODE_CLASS (mode) == MODE_INT
1631 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1634 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1635 && PAIRED_VECTOR_MODE (mode))
1641 /* The CR register can only hold CC modes. */
1642 if (CR_REGNO_P (regno))
1643 return GET_MODE_CLASS (mode) == MODE_CC;
1645 if (XER_REGNO_P (regno))
1646 return mode == PSImode;
1648 /* AltiVec only in AldyVec registers. */
1649 if (ALTIVEC_REGNO_P (regno))
1650 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1652 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1653 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1656 /* We cannot put TImode anywhere except general register and it must be able
1657 to fit within the register set. In the future, allow TImode in the
1658 Altivec or VSX registers. */
1660 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1663 /* Print interesting facts about registers. */
1665 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1669 for (r = first_regno; r <= last_regno; ++r)
1671 const char *comma = "";
1674 if (first_regno == last_regno)
1675 fprintf (stderr, "%s:\t", reg_name);
1677 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1680 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1681 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1685 fprintf (stderr, ",\n\t");
1690 if (rs6000_hard_regno_nregs[m][r] > 1)
1691 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1692 rs6000_hard_regno_nregs[m][r]);
1694 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1699 if (call_used_regs[r])
1703 fprintf (stderr, ",\n\t");
1708 len += fprintf (stderr, "%s%s", comma, "call-used");
1716 fprintf (stderr, ",\n\t");
1721 len += fprintf (stderr, "%s%s", comma, "fixed");
1727 fprintf (stderr, ",\n\t");
1731 fprintf (stderr, "%sregno = %d\n", comma, r);
1735 /* Print various interesting information with -mdebug=reg. */
1737 rs6000_debug_reg_global (void)
1739 const char *nl = (const char *)0;
1741 char costly_num[20];
1743 const char *costly_str;
1744 const char *nop_str;
1746 /* Map enum rs6000_vector to string. */
1747 static const char *rs6000_debug_vector_unit[] = {
1756 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1757 LAST_VIRTUAL_REGISTER);
1758 rs6000_debug_reg_print (0, 31, "gr");
1759 rs6000_debug_reg_print (32, 63, "fp");
1760 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1763 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1764 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1765 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1766 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1767 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1768 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1769 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1770 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1771 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1775 "d reg_class = %s\n"
1776 "f reg_class = %s\n"
1777 "v reg_class = %s\n"
1778 "wa reg_class = %s\n"
1779 "wd reg_class = %s\n"
1780 "wf reg_class = %s\n"
1781 "ws reg_class = %s\n\n",
1782 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1783 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1784 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1790 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1791 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1794 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1796 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1797 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1803 switch (rs6000_sched_costly_dep)
1805 case max_dep_latency:
1806 costly_str = "max_dep_latency";
1810 costly_str = "no_dep_costly";
1813 case all_deps_costly:
1814 costly_str = "all_deps_costly";
1817 case true_store_to_load_dep_costly:
1818 costly_str = "true_store_to_load_dep_costly";
1821 case store_to_load_dep_costly:
1822 costly_str = "store_to_load_dep_costly";
1826 costly_str = costly_num;
1827 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1831 switch (rs6000_sched_insert_nops)
1833 case sched_finish_regroup_exact:
1834 nop_str = "sched_finish_regroup_exact";
1837 case sched_finish_pad_groups:
1838 nop_str = "sched_finish_pad_groups";
1841 case sched_finish_none:
1842 nop_str = "sched_finish_none";
1847 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1852 "always_hint = %s\n"
1853 "align_branch_targets = %s\n"
1854 "sched_restricted_insns_priority = %d\n"
1855 "sched_costly_dep = %s\n"
1856 "sched_insert_nops = %s\n\n",
1857 rs6000_always_hint ? "true" : "false",
1858 rs6000_align_branch_targets ? "true" : "false",
1859 (int)rs6000_sched_restricted_insns_priority,
1860 costly_str, nop_str);
1863 /* Initialize the various global tables that are based on register size. */
1865 rs6000_init_hard_regno_mode_ok (void)
1871 /* Precalculate REGNO_REG_CLASS. */
1872 rs6000_regno_regclass[0] = GENERAL_REGS;
1873 for (r = 1; r < 32; ++r)
1874 rs6000_regno_regclass[r] = BASE_REGS;
1876 for (r = 32; r < 64; ++r)
1877 rs6000_regno_regclass[r] = FLOAT_REGS;
1879 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1880 rs6000_regno_regclass[r] = NO_REGS;
1882 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1883 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1885 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1886 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1887 rs6000_regno_regclass[r] = CR_REGS;
1889 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1890 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1891 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1892 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1893 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1894 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1895 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1896 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1897 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1898 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1900 /* Precalculate vector information, this must be set up before the
1901 rs6000_hard_regno_nregs_internal below. */
1902 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1904 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1905 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1906 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1909 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1910 rs6000_constraints[c] = NO_REGS;
1912 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1913 believes it can use native alignment or still uses 128-bit alignment. */
1914 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1925 /* V2DF mode, VSX only. */
1928 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1929 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1930 rs6000_vector_align[V2DFmode] = align64;
1933 /* V4SF mode, either VSX or Altivec. */
1936 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1937 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1938 rs6000_vector_align[V4SFmode] = align32;
1940 else if (TARGET_ALTIVEC)
1942 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1943 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1944 rs6000_vector_align[V4SFmode] = align32;
1947 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1951 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1952 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1953 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1954 rs6000_vector_align[V4SImode] = align32;
1955 rs6000_vector_align[V8HImode] = align32;
1956 rs6000_vector_align[V16QImode] = align32;
1960 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1961 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1962 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1966 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1967 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1968 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1972 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1973 Altivec doesn't have 64-bit support. */
1976 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1977 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1978 rs6000_vector_align[V2DImode] = align64;
1981 /* DFmode, see if we want to use the VSX unit. */
1982 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1984 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1985 rs6000_vector_mem[DFmode]
1986 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1987 rs6000_vector_align[DFmode] = align64;
1990 /* TODO add SPE and paired floating point vector support. */
1992 /* Register class constaints for the constraints that depend on compile
1994 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1995 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1997 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1998 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2002 /* At present, we just use VSX_REGS, but we have different constraints
2003 based on the use, in case we want to fine tune the default register
2004 class used. wa = any VSX register, wf = register class to use for
2005 V4SF, wd = register class to use for V2DF, and ws = register classs to
2006 use for DF scalars. */
2007 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2008 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2009 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2010 if (TARGET_VSX_SCALAR_DOUBLE)
2011 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2015 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2017 /* Set up the reload helper functions. */
2018 if (TARGET_VSX || TARGET_ALTIVEC)
2022 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2023 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2024 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2025 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2026 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2027 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2028 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2029 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2030 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2031 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2032 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2033 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2037 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2038 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2039 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2040 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2041 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2042 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2043 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2044 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2045 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2046 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2047 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2048 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2052 /* Precalculate HARD_REGNO_NREGS. */
2053 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2054 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2055 rs6000_hard_regno_nregs[m][r]
2056 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2058 /* Precalculate HARD_REGNO_MODE_OK. */
2059 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2060 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2061 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2062 rs6000_hard_regno_mode_ok_p[m][r] = true;
2064 /* Precalculate CLASS_MAX_NREGS sizes. */
2065 for (c = 0; c < LIM_REG_CLASSES; ++c)
2069 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2070 reg_size = UNITS_PER_VSX_WORD;
2072 else if (c == ALTIVEC_REGS)
2073 reg_size = UNITS_PER_ALTIVEC_WORD;
2075 else if (c == FLOAT_REGS)
2076 reg_size = UNITS_PER_FP_WORD;
2079 reg_size = UNITS_PER_WORD;
2081 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2082 rs6000_class_max_nregs[m][c]
2083 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2086 if (TARGET_E500_DOUBLE)
2087 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2089 if (TARGET_DEBUG_REG)
2090 rs6000_debug_reg_global ();
2094 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2097 darwin_rs6000_override_options (void)
2099 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2101 rs6000_altivec_abi = 1;
2102 TARGET_ALTIVEC_VRSAVE = 1;
2103 if (DEFAULT_ABI == ABI_DARWIN)
2105 if (MACHO_DYNAMIC_NO_PIC_P)
2108 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2111 else if (flag_pic == 1)
2116 if (TARGET_64BIT && ! TARGET_POWERPC64)
2118 target_flags |= MASK_POWERPC64;
2119 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2123 rs6000_default_long_calls = 1;
2124 target_flags |= MASK_SOFT_FLOAT;
2127 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2129 if (!flag_mkernel && !flag_apple_kext
2131 && ! (target_flags_explicit & MASK_ALTIVEC))
2132 target_flags |= MASK_ALTIVEC;
2134 /* Unless the user (not the configurer) has explicitly overridden
2135 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2136 G4 unless targetting the kernel. */
2139 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2140 && ! (target_flags_explicit & MASK_ALTIVEC)
2141 && ! rs6000_select[1].string)
2143 target_flags |= MASK_ALTIVEC;
2148 /* If not otherwise specified by a target, make 'long double' equivalent to
2151 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2152 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2155 /* Override command line options. Mostly we process the processor
2156 type and sometimes adjust other TARGET_ options. */
2159 rs6000_override_options (const char *default_cpu)
2162 struct rs6000_cpu_select *ptr;
2165 /* Simplifications for entries below. */
2168 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2169 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2172 /* This table occasionally claims that a processor does not support
2173 a particular feature even though it does, but the feature is slower
2174 than the alternative. Thus, it shouldn't be relied on as a
2175 complete description of the processor's support.
2177 Please keep this list in order, and don't forget to update the
2178 documentation in invoke.texi when adding a new processor or
2182 const char *const name; /* Canonical processor name. */
2183 const enum processor_type processor; /* Processor type enum value. */
2184 const int target_enable; /* Target flags to enable. */
2185 } const processor_target_table[]
2186 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2187 {"403", PROCESSOR_PPC403,
2188 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2189 {"405", PROCESSOR_PPC405,
2190 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2191 {"405fp", PROCESSOR_PPC405,
2192 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2193 {"440", PROCESSOR_PPC440,
2194 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2195 {"440fp", PROCESSOR_PPC440,
2196 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2197 {"464", PROCESSOR_PPC440,
2198 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2199 {"464fp", PROCESSOR_PPC440,
2200 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2201 {"476", PROCESSOR_PPC476,
2202 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2203 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2204 {"476fp", PROCESSOR_PPC476,
2205 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2206 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2207 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2208 {"601", PROCESSOR_PPC601,
2209 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2210 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2211 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2212 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2213 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2215 {"620", PROCESSOR_PPC620,
2216 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2217 {"630", PROCESSOR_PPC630,
2218 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2219 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2220 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2221 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2222 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2223 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2224 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2225 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2226 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2228 /* 8548 has a dummy entry for now. */
2229 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2231 {"a2", PROCESSOR_PPCA2,
2232 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2233 | MASK_CMPB | MASK_NO_UPDATE },
2234 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2235 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2236 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2238 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2239 | MASK_PPC_GFXOPT | MASK_ISEL},
2240 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2241 {"970", PROCESSOR_POWER4,
2242 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2243 {"cell", PROCESSOR_CELL,
2244 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2245 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2246 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2247 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2248 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2249 {"G5", PROCESSOR_POWER4,
2250 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2251 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2252 {"power2", PROCESSOR_POWER,
2253 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2254 {"power3", PROCESSOR_PPC630,
2255 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2256 {"power4", PROCESSOR_POWER4,
2257 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2259 {"power5", PROCESSOR_POWER5,
2260 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2261 | MASK_MFCRF | MASK_POPCNTB},
2262 {"power5+", PROCESSOR_POWER5,
2263 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2264 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2265 {"power6", PROCESSOR_POWER6,
2266 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2267 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2268 {"power6x", 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
2272 {"power7", PROCESSOR_POWER7,
2273 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2274 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2275 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2276 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2277 {"powerpc64", PROCESSOR_POWERPC64,
2278 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2279 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2280 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2281 {"rios2", PROCESSOR_RIOS2,
2282 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2283 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2285 {"rs64", PROCESSOR_RS64A,
2286 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2289 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2291 /* Some OSs don't support saving the high part of 64-bit registers on
2292 context switch. Other OSs don't support saving Altivec registers.
2293 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2294 settings; if the user wants either, the user must explicitly specify
2295 them and we won't interfere with the user's specification. */
2298 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2299 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2300 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2301 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2302 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2303 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2306 /* Numerous experiment shows that IRA based loop pressure
2307 calculation works better for RTL loop invariant motion on targets
2308 with enough (>= 32) registers. It is an expensive optimization.
2309 So it is on only for peak performance. */
2311 flag_ira_loop_pressure = 1;
2313 /* Set the pointer size. */
2316 rs6000_pmode = (int)DImode;
2317 rs6000_pointer_size = 64;
2321 rs6000_pmode = (int)SImode;
2322 rs6000_pointer_size = 32;
2325 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2326 #ifdef OS_MISSING_POWERPC64
2327 if (OS_MISSING_POWERPC64)
2328 set_masks &= ~MASK_POWERPC64;
2330 #ifdef OS_MISSING_ALTIVEC
2331 if (OS_MISSING_ALTIVEC)
2332 set_masks &= ~MASK_ALTIVEC;
2335 /* Don't override by the processor default if given explicitly. */
2336 set_masks &= ~target_flags_explicit;
2338 /* Identify the processor type. */
2339 rs6000_select[0].string = default_cpu;
2340 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2342 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2344 ptr = &rs6000_select[i];
2345 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2347 for (j = 0; j < ptt_size; j++)
2348 if (! strcmp (ptr->string, processor_target_table[j].name))
2350 if (ptr->set_tune_p)
2351 rs6000_cpu = processor_target_table[j].processor;
2353 if (ptr->set_arch_p)
2355 target_flags &= ~set_masks;
2356 target_flags |= (processor_target_table[j].target_enable
2363 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2367 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2368 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2371 error ("AltiVec not supported in this target");
2373 error ("Spe not supported in this target");
2376 /* Disable Cell microcode if we are optimizing for the Cell
2377 and not optimizing for size. */
2378 if (rs6000_gen_cell_microcode == -1)
2379 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2382 /* If we are optimizing big endian systems for space and it's OK to
2383 use instructions that would be microcoded on the Cell, use the
2384 load/store multiple and string instructions. */
2385 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2386 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2388 /* Don't allow -mmultiple or -mstring on little endian systems
2389 unless the cpu is a 750, because the hardware doesn't support the
2390 instructions used in little endian mode, and causes an alignment
2391 trap. The 750 does not cause an alignment trap (except when the
2392 target is unaligned). */
2394 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2396 if (TARGET_MULTIPLE)
2398 target_flags &= ~MASK_MULTIPLE;
2399 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2400 warning (0, "-mmultiple is not supported on little endian systems");
2405 target_flags &= ~MASK_STRING;
2406 if ((target_flags_explicit & MASK_STRING) != 0)
2407 warning (0, "-mstring is not supported on little endian systems");
2411 /* Add some warnings for VSX. */
2414 const char *msg = NULL;
2415 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2416 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2418 if (target_flags_explicit & MASK_VSX)
2419 msg = N_("-mvsx requires hardware floating point");
2421 target_flags &= ~ MASK_VSX;
2423 else if (TARGET_PAIRED_FLOAT)
2424 msg = N_("-mvsx and -mpaired are incompatible");
2425 /* The hardware will allow VSX and little endian, but until we make sure
2426 things like vector select, etc. work don't allow VSX on little endian
2427 systems at this point. */
2428 else if (!BYTES_BIG_ENDIAN)
2429 msg = N_("-mvsx used with little endian code");
2430 else if (TARGET_AVOID_XFORM > 0)
2431 msg = N_("-mvsx needs indexed addressing");
2432 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2434 if (target_flags_explicit & MASK_VSX)
2435 msg = N_("-mvsx and -mno-altivec are incompatible");
2437 msg = N_("-mno-altivec disables vsx");
2443 target_flags &= ~ MASK_VSX;
2445 else if (TARGET_VSX && !TARGET_ALTIVEC)
2446 target_flags |= MASK_ALTIVEC;
2449 /* Set debug flags */
2450 if (rs6000_debug_name)
2452 if (! strcmp (rs6000_debug_name, "all"))
2453 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2454 = rs6000_debug_addr = rs6000_debug_cost = 1;
2455 else if (! strcmp (rs6000_debug_name, "stack"))
2456 rs6000_debug_stack = 1;
2457 else if (! strcmp (rs6000_debug_name, "arg"))
2458 rs6000_debug_arg = 1;
2459 else if (! strcmp (rs6000_debug_name, "reg"))
2460 rs6000_debug_reg = 1;
2461 else if (! strcmp (rs6000_debug_name, "addr"))
2462 rs6000_debug_addr = 1;
2463 else if (! strcmp (rs6000_debug_name, "cost"))
2464 rs6000_debug_cost = 1;
2466 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2468 /* If the appropriate debug option is enabled, replace the target hooks
2469 with debug versions that call the real version and then prints
2470 debugging information. */
2471 if (TARGET_DEBUG_COST)
2473 targetm.rtx_costs = rs6000_debug_rtx_costs;
2474 targetm.address_cost = rs6000_debug_address_cost;
2475 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2478 if (TARGET_DEBUG_ADDR)
2480 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2481 targetm.legitimize_address = rs6000_debug_legitimize_address;
2482 rs6000_secondary_reload_class_ptr
2483 = rs6000_debug_secondary_reload_class;
2484 rs6000_secondary_memory_needed_ptr
2485 = rs6000_debug_secondary_memory_needed;
2486 rs6000_cannot_change_mode_class_ptr
2487 = rs6000_debug_cannot_change_mode_class;
2488 rs6000_preferred_reload_class_ptr
2489 = rs6000_debug_preferred_reload_class;
2490 rs6000_legitimize_reload_address_ptr
2491 = rs6000_debug_legitimize_reload_address;
2492 rs6000_mode_dependent_address_ptr
2493 = rs6000_debug_mode_dependent_address;
2497 if (rs6000_traceback_name)
2499 if (! strncmp (rs6000_traceback_name, "full", 4))
2500 rs6000_traceback = traceback_full;
2501 else if (! strncmp (rs6000_traceback_name, "part", 4))
2502 rs6000_traceback = traceback_part;
2503 else if (! strncmp (rs6000_traceback_name, "no", 2))
2504 rs6000_traceback = traceback_none;
2506 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2507 rs6000_traceback_name);
2510 if (!rs6000_explicit_options.long_double)
2511 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2513 #ifndef POWERPC_LINUX
2514 if (!rs6000_explicit_options.ieee)
2515 rs6000_ieeequad = 1;
2518 /* Enable Altivec ABI for AIX -maltivec. */
2519 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2520 rs6000_altivec_abi = 1;
2522 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2523 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2524 be explicitly overridden in either case. */
2527 if (!rs6000_explicit_options.altivec_abi
2528 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2529 rs6000_altivec_abi = 1;
2531 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2532 if (!rs6000_explicit_options.vrsave)
2533 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2536 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2537 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2539 rs6000_darwin64_abi = 1;
2541 darwin_one_byte_bool = 1;
2543 /* Default to natural alignment, for better performance. */
2544 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2547 /* Place FP constants in the constant pool instead of TOC
2548 if section anchors enabled. */
2549 if (flag_section_anchors)
2550 TARGET_NO_FP_IN_TOC = 1;
2552 /* Handle -mtls-size option. */
2553 rs6000_parse_tls_size_option ();
2555 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2556 SUBTARGET_OVERRIDE_OPTIONS;
2558 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2559 SUBSUBTARGET_OVERRIDE_OPTIONS;
2561 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2562 SUB3TARGET_OVERRIDE_OPTIONS;
2565 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2566 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2568 /* The e500 and e500mc do not have string instructions, and we set
2569 MASK_STRING above when optimizing for size. */
2570 if ((target_flags & MASK_STRING) != 0)
2571 target_flags = target_flags & ~MASK_STRING;
2573 else if (rs6000_select[1].string != NULL)
2575 /* For the powerpc-eabispe configuration, we set all these by
2576 default, so let's unset them if we manually set another
2577 CPU that is not the E500. */
2578 if (!rs6000_explicit_options.spe_abi)
2580 if (!rs6000_explicit_options.spe)
2582 if (!rs6000_explicit_options.float_gprs)
2583 rs6000_float_gprs = 0;
2584 if (!(target_flags_explicit & MASK_ISEL))
2585 target_flags &= ~MASK_ISEL;
2588 /* Detect invalid option combinations with E500. */
2591 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2592 && rs6000_cpu != PROCESSOR_POWER5
2593 && rs6000_cpu != PROCESSOR_POWER6
2594 && rs6000_cpu != PROCESSOR_POWER7
2595 && rs6000_cpu != PROCESSOR_PPCA2
2596 && rs6000_cpu != PROCESSOR_CELL);
2597 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2598 || rs6000_cpu == PROCESSOR_POWER5
2599 || rs6000_cpu == PROCESSOR_POWER7);
2600 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2601 || rs6000_cpu == PROCESSOR_POWER5
2602 || rs6000_cpu == PROCESSOR_POWER6
2603 || rs6000_cpu == PROCESSOR_POWER7
2604 || rs6000_cpu == PROCESSOR_PPCE500MC
2605 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2607 /* Allow debug switches to override the above settings. */
2608 if (TARGET_ALWAYS_HINT > 0)
2609 rs6000_always_hint = TARGET_ALWAYS_HINT;
2611 if (TARGET_SCHED_GROUPS > 0)
2612 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2614 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2615 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2617 rs6000_sched_restricted_insns_priority
2618 = (rs6000_sched_groups ? 1 : 0);
2620 /* Handle -msched-costly-dep option. */
2621 rs6000_sched_costly_dep
2622 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2624 if (rs6000_sched_costly_dep_str)
2626 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2627 rs6000_sched_costly_dep = no_dep_costly;
2628 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2629 rs6000_sched_costly_dep = all_deps_costly;
2630 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2631 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2632 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2633 rs6000_sched_costly_dep = store_to_load_dep_costly;
2635 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2636 atoi (rs6000_sched_costly_dep_str));
2639 /* Handle -minsert-sched-nops option. */
2640 rs6000_sched_insert_nops
2641 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2643 if (rs6000_sched_insert_nops_str)
2645 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2646 rs6000_sched_insert_nops = sched_finish_none;
2647 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2648 rs6000_sched_insert_nops = sched_finish_pad_groups;
2649 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2650 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2652 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2653 atoi (rs6000_sched_insert_nops_str));
2656 #ifdef TARGET_REGNAMES
2657 /* If the user desires alternate register names, copy in the
2658 alternate names now. */
2659 if (TARGET_REGNAMES)
2660 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2663 /* Set aix_struct_return last, after the ABI is determined.
2664 If -maix-struct-return or -msvr4-struct-return was explicitly
2665 used, don't override with the ABI default. */
2666 if (!rs6000_explicit_options.aix_struct_ret)
2667 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2669 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2670 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2673 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2675 /* We can only guarantee the availability of DI pseudo-ops when
2676 assembling for 64-bit targets. */
2679 targetm.asm_out.aligned_op.di = NULL;
2680 targetm.asm_out.unaligned_op.di = NULL;
2683 /* Set branch target alignment, if not optimizing for size. */
2686 /* Cell wants to be aligned 8byte for dual issue. */
2687 if (rs6000_cpu == PROCESSOR_CELL)
2689 if (align_functions <= 0)
2690 align_functions = 8;
2691 if (align_jumps <= 0)
2693 if (align_loops <= 0)
2696 if (rs6000_align_branch_targets)
2698 if (align_functions <= 0)
2699 align_functions = 16;
2700 if (align_jumps <= 0)
2702 if (align_loops <= 0)
2705 if (align_jumps_max_skip <= 0)
2706 align_jumps_max_skip = 15;
2707 if (align_loops_max_skip <= 0)
2708 align_loops_max_skip = 15;
2711 /* Arrange to save and restore machine status around nested functions. */
2712 init_machine_status = rs6000_init_machine_status;
2714 /* We should always be splitting complex arguments, but we can't break
2715 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2716 if (DEFAULT_ABI != ABI_AIX)
2717 targetm.calls.split_complex_arg = NULL;
2719 /* Initialize rs6000_cost with the appropriate target costs. */
2721 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2725 case PROCESSOR_RIOS1:
2726 rs6000_cost = &rios1_cost;
2729 case PROCESSOR_RIOS2:
2730 rs6000_cost = &rios2_cost;
2733 case PROCESSOR_RS64A:
2734 rs6000_cost = &rs64a_cost;
2737 case PROCESSOR_MPCCORE:
2738 rs6000_cost = &mpccore_cost;
2741 case PROCESSOR_PPC403:
2742 rs6000_cost = &ppc403_cost;
2745 case PROCESSOR_PPC405:
2746 rs6000_cost = &ppc405_cost;
2749 case PROCESSOR_PPC440:
2750 rs6000_cost = &ppc440_cost;
2753 case PROCESSOR_PPC476:
2754 rs6000_cost = &ppc476_cost;
2757 case PROCESSOR_PPC601:
2758 rs6000_cost = &ppc601_cost;
2761 case PROCESSOR_PPC603:
2762 rs6000_cost = &ppc603_cost;
2765 case PROCESSOR_PPC604:
2766 rs6000_cost = &ppc604_cost;
2769 case PROCESSOR_PPC604e:
2770 rs6000_cost = &ppc604e_cost;
2773 case PROCESSOR_PPC620:
2774 rs6000_cost = &ppc620_cost;
2777 case PROCESSOR_PPC630:
2778 rs6000_cost = &ppc630_cost;
2781 case PROCESSOR_CELL:
2782 rs6000_cost = &ppccell_cost;
2785 case PROCESSOR_PPC750:
2786 case PROCESSOR_PPC7400:
2787 rs6000_cost = &ppc750_cost;
2790 case PROCESSOR_PPC7450:
2791 rs6000_cost = &ppc7450_cost;
2794 case PROCESSOR_PPC8540:
2795 rs6000_cost = &ppc8540_cost;
2798 case PROCESSOR_PPCE300C2:
2799 case PROCESSOR_PPCE300C3:
2800 rs6000_cost = &ppce300c2c3_cost;
2803 case PROCESSOR_PPCE500MC:
2804 rs6000_cost = &ppce500mc_cost;
2807 case PROCESSOR_PPCE500MC64:
2808 rs6000_cost = &ppce500mc64_cost;
2811 case PROCESSOR_POWER4:
2812 case PROCESSOR_POWER5:
2813 rs6000_cost = &power4_cost;
2816 case PROCESSOR_POWER6:
2817 rs6000_cost = &power6_cost;
2820 case PROCESSOR_POWER7:
2821 rs6000_cost = &power7_cost;
2824 case PROCESSOR_PPCA2:
2825 rs6000_cost = &ppca2_cost;
2832 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2833 set_param_value ("simultaneous-prefetches",
2834 rs6000_cost->simultaneous_prefetches);
2835 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2836 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2837 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2838 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2839 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2840 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2842 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2843 can be optimized to ap = __builtin_next_arg (0). */
2844 if (DEFAULT_ABI != ABI_V4)
2845 targetm.expand_builtin_va_start = NULL;
2847 /* Set up single/double float flags.
2848 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2849 then set both flags. */
2850 if (TARGET_HARD_FLOAT && TARGET_FPRS
2851 && rs6000_single_float == 0 && rs6000_double_float == 0)
2852 rs6000_single_float = rs6000_double_float = 1;
2854 /* Reset single and double FP flags if target is E500. */
2857 rs6000_single_float = rs6000_double_float = 0;
2858 if (TARGET_E500_SINGLE)
2859 rs6000_single_float = 1;
2860 if (TARGET_E500_DOUBLE)
2861 rs6000_single_float = rs6000_double_float = 1;
2864 /* If not explicitly specified via option, decide whether to generate indexed
2865 load/store instructions. */
2866 if (TARGET_AVOID_XFORM == -1)
2867 /* Avoid indexed addressing when targeting Power6 in order to avoid
2868 the DERAT mispredict penalty. */
2869 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2871 rs6000_init_hard_regno_mode_ok ();
2874 /* Implement targetm.vectorize.builtin_mask_for_load. */
2876 rs6000_builtin_mask_for_load (void)
2878 if (TARGET_ALTIVEC || TARGET_VSX)
2879 return altivec_builtin_mask_for_load;
2884 /* Implement targetm.vectorize.builtin_conversion.
2885 Returns a decl of a function that implements conversion of an integer vector
2886 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2887 side of the conversion.
2888 Return NULL_TREE if it is not available. */
2890 rs6000_builtin_conversion (unsigned int tcode, tree type)
2892 enum tree_code code = (enum tree_code) tcode;
2896 case FIX_TRUNC_EXPR:
2897 switch (TYPE_MODE (type))
2900 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2903 return TYPE_UNSIGNED (type)
2904 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2905 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2908 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2911 return TYPE_UNSIGNED (type)
2912 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2913 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2920 switch (TYPE_MODE (type))
2923 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2926 return TYPE_UNSIGNED (type)
2927 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2928 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2931 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2934 return TYPE_UNSIGNED (type)
2935 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2936 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2947 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2949 rs6000_builtin_mul_widen_even (tree type)
2951 if (!TARGET_ALTIVEC)
2954 switch (TYPE_MODE (type))
2957 return TYPE_UNSIGNED (type)
2958 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2959 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2962 return TYPE_UNSIGNED (type)
2963 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2964 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2970 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2972 rs6000_builtin_mul_widen_odd (tree type)
2974 if (!TARGET_ALTIVEC)
2977 switch (TYPE_MODE (type))
2980 return TYPE_UNSIGNED (type)
2981 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2982 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2985 return TYPE_UNSIGNED (type)
2986 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2987 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2994 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2995 after applying N number of iterations. This routine does not determine
2996 how may iterations are required to reach desired alignment. */
2999 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3006 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3009 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3019 /* Assuming that all other types are naturally aligned. CHECKME! */
3024 /* Return true if the vector misalignment factor is supported by the
3027 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3034 /* Return if movmisalign pattern is not supported for this mode. */
3035 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3039 if (misalignment == -1)
3041 /* misalignment factor is unknown at compile time but we know
3042 it's word aligned. */
3043 if (rs6000_vector_alignment_reachable (type, is_packed))
3047 /* VSX supports word-aligned vector. */
3048 if (misalignment % 4 == 0)
3054 /* Implement targetm.vectorize.builtin_vec_perm. */
3056 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3058 tree inner_type = TREE_TYPE (type);
3059 bool uns_p = TYPE_UNSIGNED (inner_type);
3062 *mask_element_type = unsigned_char_type_node;
3064 switch (TYPE_MODE (type))
3068 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3069 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3074 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3075 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3080 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3081 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3085 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3089 if (!TARGET_ALLOW_DF_PERMUTE)
3092 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3096 if (!TARGET_ALLOW_DF_PERMUTE)
3100 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3101 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3112 /* Handle generic options of the form -mfoo=yes/no.
3113 NAME is the option name.
3114 VALUE is the option value.
3115 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3116 whether the option value is 'yes' or 'no' respectively. */
3118 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3122 else if (!strcmp (value, "yes"))
3124 else if (!strcmp (value, "no"))
3127 error ("unknown -m%s= option specified: '%s'", name, value);
3130 /* Validate and record the size specified with the -mtls-size option. */
3133 rs6000_parse_tls_size_option (void)
3135 if (rs6000_tls_size_string == 0)
3137 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3138 rs6000_tls_size = 16;
3139 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3140 rs6000_tls_size = 32;
3141 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3142 rs6000_tls_size = 64;
3144 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3148 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3150 if (DEFAULT_ABI == ABI_DARWIN)
3151 /* The Darwin libraries never set errno, so we might as well
3152 avoid calling them when that's the only reason we would. */
3153 flag_errno_math = 0;
3155 /* Double growth factor to counter reduced min jump length. */
3156 set_param_value ("max-grow-copy-bb-insns", 16);
3158 /* Enable section anchors by default.
3159 Skip section anchors for Objective C and Objective C++
3160 until front-ends fixed. */
3161 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3162 flag_section_anchors = 2;
3165 static enum fpu_type_t
3166 rs6000_parse_fpu_option (const char *option)
3168 if (!strcmp("none", option)) return FPU_NONE;
3169 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3170 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3171 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3172 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3173 error("unknown value %s for -mfpu", option);
3177 /* Returns a function decl for a vectorized version of the builtin function
3178 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3179 if it is not available. */
3182 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3185 enum machine_mode in_mode, out_mode;
3188 if (TREE_CODE (type_out) != VECTOR_TYPE
3189 || TREE_CODE (type_in) != VECTOR_TYPE
3190 || !TARGET_VECTORIZE_BUILTINS)
3193 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3194 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3195 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3196 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3200 case BUILT_IN_COPYSIGN:
3201 if (VECTOR_UNIT_VSX_P (V2DFmode)
3202 && out_mode == DFmode && out_n == 2
3203 && in_mode == DFmode && in_n == 2)
3204 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3206 case BUILT_IN_COPYSIGNF:
3207 if (out_mode != SFmode || out_n != 4
3208 || in_mode != SFmode || in_n != 4)
3210 if (VECTOR_UNIT_VSX_P (V4SFmode))
3211 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3212 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3213 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3216 if (VECTOR_UNIT_VSX_P (V2DFmode)
3217 && out_mode == DFmode && out_n == 2
3218 && in_mode == DFmode && in_n == 2)
3219 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3221 case BUILT_IN_SQRTF:
3222 if (VECTOR_UNIT_VSX_P (V4SFmode)
3223 && out_mode == SFmode && out_n == 4
3224 && in_mode == SFmode && in_n == 4)
3225 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3228 if (VECTOR_UNIT_VSX_P (V2DFmode)
3229 && out_mode == DFmode && out_n == 2
3230 && in_mode == DFmode && in_n == 2)
3231 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3233 case BUILT_IN_CEILF:
3234 if (out_mode != SFmode || out_n != 4
3235 || in_mode != SFmode || in_n != 4)
3237 if (VECTOR_UNIT_VSX_P (V4SFmode))
3238 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3239 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3240 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3242 case BUILT_IN_FLOOR:
3243 if (VECTOR_UNIT_VSX_P (V2DFmode)
3244 && out_mode == DFmode && out_n == 2
3245 && in_mode == DFmode && in_n == 2)
3246 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3248 case BUILT_IN_FLOORF:
3249 if (out_mode != SFmode || out_n != 4
3250 || in_mode != SFmode || in_n != 4)
3252 if (VECTOR_UNIT_VSX_P (V4SFmode))
3253 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3254 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3255 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3257 case BUILT_IN_TRUNC:
3258 if (VECTOR_UNIT_VSX_P (V2DFmode)
3259 && out_mode == DFmode && out_n == 2
3260 && in_mode == DFmode && in_n == 2)
3261 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3263 case BUILT_IN_TRUNCF:
3264 if (out_mode != SFmode || out_n != 4
3265 || in_mode != SFmode || in_n != 4)
3267 if (VECTOR_UNIT_VSX_P (V4SFmode))
3268 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3269 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3270 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3272 case BUILT_IN_NEARBYINT:
3273 if (VECTOR_UNIT_VSX_P (V2DFmode)
3274 && flag_unsafe_math_optimizations
3275 && out_mode == DFmode && out_n == 2
3276 && in_mode == DFmode && in_n == 2)
3277 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3279 case BUILT_IN_NEARBYINTF:
3280 if (VECTOR_UNIT_VSX_P (V4SFmode)
3281 && flag_unsafe_math_optimizations
3282 && out_mode == SFmode && out_n == 4
3283 && in_mode == SFmode && in_n == 4)
3284 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3287 if (VECTOR_UNIT_VSX_P (V2DFmode)
3288 && !flag_trapping_math
3289 && out_mode == DFmode && out_n == 2
3290 && in_mode == DFmode && in_n == 2)
3291 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3293 case BUILT_IN_RINTF:
3294 if (VECTOR_UNIT_VSX_P (V4SFmode)
3295 && !flag_trapping_math
3296 && out_mode == SFmode && out_n == 4
3297 && in_mode == SFmode && in_n == 4)
3298 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3307 /* Implement TARGET_HANDLE_OPTION. */
3310 rs6000_handle_option (size_t code, const char *arg, int value)
3312 enum fpu_type_t fpu_type = FPU_NONE;
3318 target_flags &= ~(MASK_POWER | MASK_POWER2
3319 | MASK_MULTIPLE | MASK_STRING);
3320 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3321 | MASK_MULTIPLE | MASK_STRING);
3323 case OPT_mno_powerpc:
3324 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3325 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3326 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3327 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3330 target_flags &= ~MASK_MINIMAL_TOC;
3331 TARGET_NO_FP_IN_TOC = 0;
3332 TARGET_NO_SUM_IN_TOC = 0;
3333 target_flags_explicit |= MASK_MINIMAL_TOC;
3334 #ifdef TARGET_USES_SYSV4_OPT
3335 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3336 just the same as -mminimal-toc. */
3337 target_flags |= MASK_MINIMAL_TOC;
3338 target_flags_explicit |= MASK_MINIMAL_TOC;
3342 #ifdef TARGET_USES_SYSV4_OPT
3344 /* Make -mtoc behave like -mminimal-toc. */
3345 target_flags |= MASK_MINIMAL_TOC;
3346 target_flags_explicit |= MASK_MINIMAL_TOC;
3350 #ifdef TARGET_USES_AIX64_OPT
3355 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3356 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3357 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3360 #ifdef TARGET_USES_AIX64_OPT
3365 target_flags &= ~MASK_POWERPC64;
3366 target_flags_explicit |= MASK_POWERPC64;
3369 case OPT_minsert_sched_nops_:
3370 rs6000_sched_insert_nops_str = arg;
3373 case OPT_mminimal_toc:
3376 TARGET_NO_FP_IN_TOC = 0;
3377 TARGET_NO_SUM_IN_TOC = 0;
3384 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3385 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3392 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3393 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3397 case OPT_mpowerpc_gpopt:
3398 case OPT_mpowerpc_gfxopt:
3401 target_flags |= MASK_POWERPC;
3402 target_flags_explicit |= MASK_POWERPC;
3406 case OPT_maix_struct_return:
3407 case OPT_msvr4_struct_return:
3408 rs6000_explicit_options.aix_struct_ret = true;
3412 rs6000_explicit_options.vrsave = true;
3413 TARGET_ALTIVEC_VRSAVE = value;
3417 rs6000_explicit_options.vrsave = true;
3418 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3422 target_flags_explicit |= MASK_ISEL;
3424 rs6000_parse_yes_no_option ("isel", arg, &isel);
3426 target_flags |= MASK_ISEL;
3428 target_flags &= ~MASK_ISEL;
3432 rs6000_explicit_options.spe = true;
3437 rs6000_explicit_options.spe = true;
3438 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3442 rs6000_debug_name = arg;
3445 #ifdef TARGET_USES_SYSV4_OPT
3447 rs6000_abi_name = arg;
3451 rs6000_sdata_name = arg;
3454 case OPT_mtls_size_:
3455 rs6000_tls_size_string = arg;
3458 case OPT_mrelocatable:
3461 target_flags |= MASK_MINIMAL_TOC;
3462 target_flags_explicit |= MASK_MINIMAL_TOC;
3463 TARGET_NO_FP_IN_TOC = 1;
3467 case OPT_mrelocatable_lib:
3470 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3471 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3472 TARGET_NO_FP_IN_TOC = 1;
3476 target_flags &= ~MASK_RELOCATABLE;
3477 target_flags_explicit |= MASK_RELOCATABLE;
3483 if (!strcmp (arg, "altivec"))
3485 rs6000_explicit_options.altivec_abi = true;
3486 rs6000_altivec_abi = 1;
3488 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3491 else if (! strcmp (arg, "no-altivec"))
3493 rs6000_explicit_options.altivec_abi = true;
3494 rs6000_altivec_abi = 0;
3496 else if (! strcmp (arg, "spe"))
3498 rs6000_explicit_options.spe_abi = true;
3500 rs6000_altivec_abi = 0;
3501 if (!TARGET_SPE_ABI)
3502 error ("not configured for ABI: '%s'", arg);
3504 else if (! strcmp (arg, "no-spe"))
3506 rs6000_explicit_options.spe_abi = true;
3510 /* These are here for testing during development only, do not
3511 document in the manual please. */
3512 else if (! strcmp (arg, "d64"))
3514 rs6000_darwin64_abi = 1;
3515 warning (0, "Using darwin64 ABI");
3517 else if (! strcmp (arg, "d32"))
3519 rs6000_darwin64_abi = 0;
3520 warning (0, "Using old darwin ABI");
3523 else if (! strcmp (arg, "ibmlongdouble"))
3525 rs6000_explicit_options.ieee = true;
3526 rs6000_ieeequad = 0;
3527 warning (0, "Using IBM extended precision long double");
3529 else if (! strcmp (arg, "ieeelongdouble"))
3531 rs6000_explicit_options.ieee = true;
3532 rs6000_ieeequad = 1;
3533 warning (0, "Using IEEE extended precision long double");
3538 error ("unknown ABI specified: '%s'", arg);
3544 rs6000_select[1].string = arg;
3548 rs6000_select[2].string = arg;
3551 case OPT_mtraceback_:
3552 rs6000_traceback_name = arg;
3555 case OPT_mfloat_gprs_:
3556 rs6000_explicit_options.float_gprs = true;
3557 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3558 rs6000_float_gprs = 1;
3559 else if (! strcmp (arg, "double"))
3560 rs6000_float_gprs = 2;
3561 else if (! strcmp (arg, "no"))
3562 rs6000_float_gprs = 0;
3565 error ("invalid option for -mfloat-gprs: '%s'", arg);
3570 case OPT_mlong_double_:
3571 rs6000_explicit_options.long_double = true;
3572 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3573 if (value != 64 && value != 128)
3575 error ("Unknown switch -mlong-double-%s", arg);
3576 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3580 rs6000_long_double_type_size = value;
3583 case OPT_msched_costly_dep_:
3584 rs6000_sched_costly_dep_str = arg;
3588 rs6000_explicit_options.alignment = true;
3589 if (! strcmp (arg, "power"))
3591 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3592 some C library functions, so warn about it. The flag may be
3593 useful for performance studies from time to time though, so
3594 don't disable it entirely. */
3595 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3596 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3597 " it is incompatible with the installed C and C++ libraries");
3598 rs6000_alignment_flags = MASK_ALIGN_POWER;
3600 else if (! strcmp (arg, "natural"))
3601 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3604 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3609 case OPT_msingle_float:
3610 if (!TARGET_SINGLE_FPU)
3611 warning (0, "-msingle-float option equivalent to -mhard-float");
3612 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3613 rs6000_double_float = 0;
3614 target_flags &= ~MASK_SOFT_FLOAT;
3615 target_flags_explicit |= MASK_SOFT_FLOAT;
3618 case OPT_mdouble_float:
3619 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3620 rs6000_single_float = 1;
3621 target_flags &= ~MASK_SOFT_FLOAT;
3622 target_flags_explicit |= MASK_SOFT_FLOAT;
3625 case OPT_msimple_fpu:
3626 if (!TARGET_SINGLE_FPU)
3627 warning (0, "-msimple-fpu option ignored");
3630 case OPT_mhard_float:
3631 /* -mhard_float implies -msingle-float and -mdouble-float. */
3632 rs6000_single_float = rs6000_double_float = 1;
3635 case OPT_msoft_float:
3636 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3637 rs6000_single_float = rs6000_double_float = 0;
3641 fpu_type = rs6000_parse_fpu_option(arg);
3642 if (fpu_type != FPU_NONE)
3643 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3645 target_flags &= ~MASK_SOFT_FLOAT;
3646 target_flags_explicit |= MASK_SOFT_FLOAT;
3647 rs6000_xilinx_fpu = 1;
3648 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3649 rs6000_single_float = 1;
3650 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3651 rs6000_single_float = rs6000_double_float = 1;
3652 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3653 rs6000_simple_fpu = 1;
3657 /* -mfpu=none is equivalent to -msoft-float */
3658 target_flags |= MASK_SOFT_FLOAT;
3659 target_flags_explicit |= MASK_SOFT_FLOAT;
3660 rs6000_single_float = rs6000_double_float = 0;
3667 /* Do anything needed at the start of the asm file. */
3670 rs6000_file_start (void)
3674 const char *start = buffer;
3675 struct rs6000_cpu_select *ptr;
3676 const char *default_cpu = TARGET_CPU_DEFAULT;
3677 FILE *file = asm_out_file;
3679 default_file_start ();
3681 #ifdef TARGET_BI_ARCH
3682 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3686 if (flag_verbose_asm)
3688 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3689 rs6000_select[0].string = default_cpu;
3691 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3693 ptr = &rs6000_select[i];
3694 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3696 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3701 if (PPC405_ERRATUM77)
3703 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3707 #ifdef USING_ELFOS_H
3708 switch (rs6000_sdata)
3710 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3711 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3712 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3713 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3716 if (rs6000_sdata && g_switch_value)
3718 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3728 #ifdef HAVE_AS_GNU_ATTRIBUTE
3729 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3731 fprintf (file, "\t.gnu_attribute 4, %d\n",
3732 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3733 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3735 fprintf (file, "\t.gnu_attribute 8, %d\n",
3736 (TARGET_ALTIVEC_ABI ? 2
3737 : TARGET_SPE_ABI ? 3
3739 fprintf (file, "\t.gnu_attribute 12, %d\n",
3740 aix_struct_return ? 2 : 1);
3745 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3747 switch_to_section (toc_section);
3748 switch_to_section (text_section);
3753 /* Return nonzero if this function is known to have a null epilogue. */
3756 direct_return (void)
3758 if (reload_completed)
3760 rs6000_stack_t *info = rs6000_stack_info ();
3762 if (info->first_gp_reg_save == 32
3763 && info->first_fp_reg_save == 64
3764 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3765 && ! info->lr_save_p
3766 && ! info->cr_save_p
3767 && info->vrsave_mask == 0
3775 /* Return the number of instructions it takes to form a constant in an
3776 integer register. */
3779 num_insns_constant_wide (HOST_WIDE_INT value)
3781 /* signed constant loadable with {cal|addi} */
3782 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3785 /* constant loadable with {cau|addis} */
3786 else if ((value & 0xffff) == 0
3787 && (value >> 31 == -1 || value >> 31 == 0))
3790 #if HOST_BITS_PER_WIDE_INT == 64
3791 else if (TARGET_POWERPC64)
3793 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3794 HOST_WIDE_INT high = value >> 31;
3796 if (high == 0 || high == -1)
3802 return num_insns_constant_wide (high) + 1;
3804 return num_insns_constant_wide (low) + 1;
3806 return (num_insns_constant_wide (high)
3807 + num_insns_constant_wide (low) + 1);
3816 num_insns_constant (rtx op, enum machine_mode mode)
3818 HOST_WIDE_INT low, high;
3820 switch (GET_CODE (op))
3823 #if HOST_BITS_PER_WIDE_INT == 64
3824 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3825 && mask64_operand (op, mode))
3829 return num_insns_constant_wide (INTVAL (op));
3832 if (mode == SFmode || mode == SDmode)
3837 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3838 if (DECIMAL_FLOAT_MODE_P (mode))
3839 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3841 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3842 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3845 if (mode == VOIDmode || mode == DImode)
3847 high = CONST_DOUBLE_HIGH (op);
3848 low = CONST_DOUBLE_LOW (op);
3855 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3856 if (DECIMAL_FLOAT_MODE_P (mode))
3857 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3859 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3860 high = l[WORDS_BIG_ENDIAN == 0];
3861 low = l[WORDS_BIG_ENDIAN != 0];
3865 return (num_insns_constant_wide (low)
3866 + num_insns_constant_wide (high));
3869 if ((high == 0 && low >= 0)
3870 || (high == -1 && low < 0))
3871 return num_insns_constant_wide (low);
3873 else if (mask64_operand (op, mode))
3877 return num_insns_constant_wide (high) + 1;
3880 return (num_insns_constant_wide (high)
3881 + num_insns_constant_wide (low) + 1);
3889 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3890 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3891 corresponding element of the vector, but for V4SFmode and V2SFmode,
3892 the corresponding "float" is interpreted as an SImode integer. */
3895 const_vector_elt_as_int (rtx op, unsigned int elt)
3897 rtx tmp = CONST_VECTOR_ELT (op, elt);
3898 if (GET_MODE (op) == V4SFmode
3899 || GET_MODE (op) == V2SFmode)
3900 tmp = gen_lowpart (SImode, tmp);
3901 return INTVAL (tmp);
3904 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3905 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3906 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3907 all items are set to the same value and contain COPIES replicas of the
3908 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3909 operand and the others are set to the value of the operand's msb. */
3912 vspltis_constant (rtx op, unsigned step, unsigned copies)
3914 enum machine_mode mode = GET_MODE (op);
3915 enum machine_mode inner = GET_MODE_INNER (mode);
3918 unsigned nunits = GET_MODE_NUNITS (mode);
3919 unsigned bitsize = GET_MODE_BITSIZE (inner);
3920 unsigned mask = GET_MODE_MASK (inner);
3922 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3923 HOST_WIDE_INT splat_val = val;
3924 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3926 /* Construct the value to be splatted, if possible. If not, return 0. */
3927 for (i = 2; i <= copies; i *= 2)
3929 HOST_WIDE_INT small_val;
3931 small_val = splat_val >> bitsize;
3933 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3935 splat_val = small_val;
3938 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3939 if (EASY_VECTOR_15 (splat_val))
3942 /* Also check if we can splat, and then add the result to itself. Do so if
3943 the value is positive, of if the splat instruction is using OP's mode;
3944 for splat_val < 0, the splat and the add should use the same mode. */
3945 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3946 && (splat_val >= 0 || (step == 1 && copies == 1)))
3949 /* Also check if are loading up the most significant bit which can be done by
3950 loading up -1 and shifting the value left by -1. */
3951 else if (EASY_VECTOR_MSB (splat_val, inner))
3957 /* Check if VAL is present in every STEP-th element, and the
3958 other elements are filled with its most significant bit. */
3959 for (i = 0; i < nunits - 1; ++i)
3961 HOST_WIDE_INT desired_val;
3962 if (((i + 1) & (step - 1)) == 0)
3965 desired_val = msb_val;
3967 if (desired_val != const_vector_elt_as_int (op, i))
3975 /* Return true if OP is of the given MODE and can be synthesized
3976 with a vspltisb, vspltish or vspltisw. */
3979 easy_altivec_constant (rtx op, enum machine_mode mode)
3981 unsigned step, copies;
3983 if (mode == VOIDmode)
3984 mode = GET_MODE (op);
3985 else if (mode != GET_MODE (op))
3988 /* Start with a vspltisw. */
3989 step = GET_MODE_NUNITS (mode) / 4;
3992 if (vspltis_constant (op, step, copies))
3995 /* Then try with a vspltish. */
4001 if (vspltis_constant (op, step, copies))
4004 /* And finally a vspltisb. */
4010 if (vspltis_constant (op, step, copies))
4016 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4017 result is OP. Abort if it is not possible. */
4020 gen_easy_altivec_constant (rtx op)
4022 enum machine_mode mode = GET_MODE (op);
4023 int nunits = GET_MODE_NUNITS (mode);
4024 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4025 unsigned step = nunits / 4;
4026 unsigned copies = 1;
4028 /* Start with a vspltisw. */
4029 if (vspltis_constant (op, step, copies))
4030 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4032 /* Then try with a vspltish. */
4038 if (vspltis_constant (op, step, copies))
4039 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4041 /* And finally a vspltisb. */
4047 if (vspltis_constant (op, step, copies))
4048 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4054 output_vec_const_move (rtx *operands)
4057 enum machine_mode mode;
4062 mode = GET_MODE (dest);
4064 if (TARGET_VSX && zero_constant (vec, mode))
4065 return "xxlxor %x0,%x0,%x0";
4070 if (zero_constant (vec, mode))
4071 return "vxor %0,%0,%0";
4073 splat_vec = gen_easy_altivec_constant (vec);
4074 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4075 operands[1] = XEXP (splat_vec, 0);
4076 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4079 switch (GET_MODE (splat_vec))
4082 return "vspltisw %0,%1";
4085 return "vspltish %0,%1";
4088 return "vspltisb %0,%1";
4095 gcc_assert (TARGET_SPE);
4097 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4098 pattern of V1DI, V4HI, and V2SF.
4100 FIXME: We should probably return # and add post reload
4101 splitters for these, but this way is so easy ;-). */
4102 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4103 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4104 operands[1] = CONST_VECTOR_ELT (vec, 0);
4105 operands[2] = CONST_VECTOR_ELT (vec, 1);
4107 return "li %0,%1\n\tevmergelo %0,%0,%0";
4109 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4112 /* Initialize TARGET of vector PAIRED to VALS. */
4115 paired_expand_vector_init (rtx target, rtx vals)
4117 enum machine_mode mode = GET_MODE (target);
4118 int n_elts = GET_MODE_NUNITS (mode);
4120 rtx x, new_rtx, tmp, constant_op, op1, op2;
4123 for (i = 0; i < n_elts; ++i)
4125 x = XVECEXP (vals, 0, i);
4126 if (!CONSTANT_P (x))
4131 /* Load from constant pool. */
4132 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4138 /* The vector is initialized only with non-constants. */
4139 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4140 XVECEXP (vals, 0, 1));
4142 emit_move_insn (target, new_rtx);
4146 /* One field is non-constant and the other one is a constant. Load the
4147 constant from the constant pool and use ps_merge instruction to
4148 construct the whole vector. */
4149 op1 = XVECEXP (vals, 0, 0);
4150 op2 = XVECEXP (vals, 0, 1);
4152 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4154 tmp = gen_reg_rtx (GET_MODE (constant_op));
4155 emit_move_insn (tmp, constant_op);
4157 if (CONSTANT_P (op1))
4158 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4160 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4162 emit_move_insn (target, new_rtx);
4166 paired_expand_vector_move (rtx operands[])
4168 rtx op0 = operands[0], op1 = operands[1];
4170 emit_move_insn (op0, op1);
4173 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4174 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4175 operands for the relation operation COND. This is a recursive
4179 paired_emit_vector_compare (enum rtx_code rcode,
4180 rtx dest, rtx op0, rtx op1,
4181 rtx cc_op0, rtx cc_op1)
4183 rtx tmp = gen_reg_rtx (V2SFmode);
4184 rtx tmp1, max, min, equal_zero;
4186 gcc_assert (TARGET_PAIRED_FLOAT);
4187 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4193 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4197 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4198 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4202 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4205 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4208 tmp1 = gen_reg_rtx (V2SFmode);
4209 max = gen_reg_rtx (V2SFmode);
4210 min = gen_reg_rtx (V2SFmode);
4211 equal_zero = gen_reg_rtx (V2SFmode);
4213 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4214 emit_insn (gen_selv2sf4
4215 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4216 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4217 emit_insn (gen_selv2sf4
4218 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4219 emit_insn (gen_subv2sf3 (tmp1, min, max));
4220 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4223 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4226 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4229 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4232 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4235 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4244 /* Emit vector conditional expression.
4245 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4246 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4249 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4250 rtx cond, rtx cc_op0, rtx cc_op1)
4252 enum rtx_code rcode = GET_CODE (cond);
4254 if (!TARGET_PAIRED_FLOAT)
4257 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4262 /* Initialize vector TARGET to VALS. */
4265 rs6000_expand_vector_init (rtx target, rtx vals)
4267 enum machine_mode mode = GET_MODE (target);
4268 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4269 int n_elts = GET_MODE_NUNITS (mode);
4270 int n_var = 0, one_var = -1;
4271 bool all_same = true, all_const_zero = true;
4275 for (i = 0; i < n_elts; ++i)
4277 x = XVECEXP (vals, 0, i);
4278 if (!CONSTANT_P (x))
4279 ++n_var, one_var = i;
4280 else if (x != CONST0_RTX (inner_mode))
4281 all_const_zero = false;
4283 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4289 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4290 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4291 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4293 /* Zero register. */
4294 emit_insn (gen_rtx_SET (VOIDmode, target,
4295 gen_rtx_XOR (mode, target, target)));
4298 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4300 /* Splat immediate. */
4301 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4306 /* Load from constant pool. */
4307 emit_move_insn (target, const_vec);
4312 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4313 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4317 rtx element = XVECEXP (vals, 0, 0);
4318 if (mode == V2DFmode)
4319 emit_insn (gen_vsx_splat_v2df (target, element));
4321 emit_insn (gen_vsx_splat_v2di (target, element));
4325 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4326 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4327 if (mode == V2DFmode)
4328 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4330 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4335 /* With single precision floating point on VSX, know that internally single
4336 precision is actually represented as a double, and either make 2 V2DF
4337 vectors, and convert these vectors to single precision, or do one
4338 conversion, and splat the result to the other elements. */
4339 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4343 rtx freg = gen_reg_rtx (V4SFmode);
4344 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4346 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4347 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4351 rtx dbl_even = gen_reg_rtx (V2DFmode);
4352 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4353 rtx flt_even = gen_reg_rtx (V4SFmode);
4354 rtx flt_odd = gen_reg_rtx (V4SFmode);
4356 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4357 copy_to_reg (XVECEXP (vals, 0, 0)),
4358 copy_to_reg (XVECEXP (vals, 0, 1))));
4359 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4360 copy_to_reg (XVECEXP (vals, 0, 2)),
4361 copy_to_reg (XVECEXP (vals, 0, 3))));
4362 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4363 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4364 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4369 /* Store value to stack temp. Load vector element. Splat. However, splat
4370 of 64-bit items is not supported on Altivec. */
4371 if (all_same && GET_MODE_SIZE (mode) <= 4)
4373 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4374 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4375 XVECEXP (vals, 0, 0));
4376 x = gen_rtx_UNSPEC (VOIDmode,
4377 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4378 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4380 gen_rtx_SET (VOIDmode,
4383 x = gen_rtx_VEC_SELECT (inner_mode, target,
4384 gen_rtx_PARALLEL (VOIDmode,
4385 gen_rtvec (1, const0_rtx)));
4386 emit_insn (gen_rtx_SET (VOIDmode, target,
4387 gen_rtx_VEC_DUPLICATE (mode, x)));
4391 /* One field is non-constant. Load constant then overwrite
4395 rtx copy = copy_rtx (vals);
4397 /* Load constant part of vector, substitute neighboring value for
4399 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4400 rs6000_expand_vector_init (target, copy);
4402 /* Insert variable. */
4403 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4407 /* Construct the vector in memory one field at a time
4408 and load the whole vector. */
4409 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4410 for (i = 0; i < n_elts; i++)
4411 emit_move_insn (adjust_address_nv (mem, inner_mode,
4412 i * GET_MODE_SIZE (inner_mode)),
4413 XVECEXP (vals, 0, i));
4414 emit_move_insn (target, mem);
4417 /* Set field ELT of TARGET to VAL. */
4420 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4422 enum machine_mode mode = GET_MODE (target);
4423 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4424 rtx reg = gen_reg_rtx (mode);
4426 int width = GET_MODE_SIZE (inner_mode);
4429 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4431 rtx (*set_func) (rtx, rtx, rtx, rtx)
4432 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4433 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4437 /* Load single variable value. */
4438 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4439 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4440 x = gen_rtx_UNSPEC (VOIDmode,
4441 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4442 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4444 gen_rtx_SET (VOIDmode,
4448 /* Linear sequence. */
4449 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4450 for (i = 0; i < 16; ++i)
4451 XVECEXP (mask, 0, i) = GEN_INT (i);
4453 /* Set permute mask to insert element into target. */
4454 for (i = 0; i < width; ++i)
4455 XVECEXP (mask, 0, elt*width + i)
4456 = GEN_INT (i + 0x10);
4457 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4458 x = gen_rtx_UNSPEC (mode,
4459 gen_rtvec (3, target, reg,
4460 force_reg (V16QImode, x)),
4462 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4465 /* Extract field ELT from VEC into TARGET. */
4468 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4470 enum machine_mode mode = GET_MODE (vec);
4471 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4474 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4476 rtx (*extract_func) (rtx, rtx, rtx)
4477 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4478 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4482 /* Allocate mode-sized buffer. */
4483 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4485 /* Add offset to field within buffer matching vector element. */
4486 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4488 /* Store single field into mode-sized buffer. */
4489 x = gen_rtx_UNSPEC (VOIDmode,
4490 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4491 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4493 gen_rtx_SET (VOIDmode,
4496 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4499 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4500 implement ANDing by the mask IN. */
4502 build_mask64_2_operands (rtx in, rtx *out)
4504 #if HOST_BITS_PER_WIDE_INT >= 64
4505 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4508 gcc_assert (GET_CODE (in) == CONST_INT);
4513 /* Assume c initially something like 0x00fff000000fffff. The idea
4514 is to rotate the word so that the middle ^^^^^^ group of zeros
4515 is at the MS end and can be cleared with an rldicl mask. We then
4516 rotate back and clear off the MS ^^ group of zeros with a
4518 c = ~c; /* c == 0xff000ffffff00000 */
4519 lsb = c & -c; /* lsb == 0x0000000000100000 */
4520 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4521 c = ~c; /* c == 0x00fff000000fffff */
4522 c &= -lsb; /* c == 0x00fff00000000000 */
4523 lsb = c & -c; /* lsb == 0x0000100000000000 */
4524 c = ~c; /* c == 0xff000fffffffffff */
4525 c &= -lsb; /* c == 0xff00000000000000 */
4527 while ((lsb >>= 1) != 0)
4528 shift++; /* shift == 44 on exit from loop */
4529 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4530 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4531 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4535 /* Assume c initially something like 0xff000f0000000000. The idea
4536 is to rotate the word so that the ^^^ middle group of zeros
4537 is at the LS end and can be cleared with an rldicr mask. We then
4538 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4540 lsb = c & -c; /* lsb == 0x0000010000000000 */
4541 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4542 c = ~c; /* c == 0x00fff0ffffffffff */
4543 c &= -lsb; /* c == 0x00fff00000000000 */
4544 lsb = c & -c; /* lsb == 0x0000100000000000 */
4545 c = ~c; /* c == 0xff000fffffffffff */
4546 c &= -lsb; /* c == 0xff00000000000000 */
4548 while ((lsb >>= 1) != 0)
4549 shift++; /* shift == 44 on exit from loop */
4550 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4551 m1 >>= shift; /* m1 == 0x0000000000000fff */
4552 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4555 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4556 masks will be all 1's. We are guaranteed more than one transition. */
4557 out[0] = GEN_INT (64 - shift);
4558 out[1] = GEN_INT (m1);
4559 out[2] = GEN_INT (shift);
4560 out[3] = GEN_INT (m2);
4568 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4571 invalid_e500_subreg (rtx op, enum machine_mode mode)
4573 if (TARGET_E500_DOUBLE)
4575 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4576 subreg:TI and reg:TF. Decimal float modes are like integer
4577 modes (only low part of each register used) for this
4579 if (GET_CODE (op) == SUBREG
4580 && (mode == SImode || mode == DImode || mode == TImode
4581 || mode == DDmode || mode == TDmode)
4582 && REG_P (SUBREG_REG (op))
4583 && (GET_MODE (SUBREG_REG (op)) == DFmode
4584 || GET_MODE (SUBREG_REG (op)) == TFmode))
4587 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4589 if (GET_CODE (op) == SUBREG
4590 && (mode == DFmode || mode == TFmode)
4591 && REG_P (SUBREG_REG (op))
4592 && (GET_MODE (SUBREG_REG (op)) == DImode
4593 || GET_MODE (SUBREG_REG (op)) == TImode
4594 || GET_MODE (SUBREG_REG (op)) == DDmode
4595 || GET_MODE (SUBREG_REG (op)) == TDmode))
4600 && GET_CODE (op) == SUBREG
4602 && REG_P (SUBREG_REG (op))
4603 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4609 /* AIX increases natural record alignment to doubleword if the first
4610 field is an FP double while the FP fields remain word aligned. */
4613 rs6000_special_round_type_align (tree type, unsigned int computed,
4614 unsigned int specified)
4616 unsigned int align = MAX (computed, specified);
4617 tree field = TYPE_FIELDS (type);
4619 /* Skip all non field decls */
4620 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4621 field = TREE_CHAIN (field);
4623 if (field != NULL && field != type)
4625 type = TREE_TYPE (field);
4626 while (TREE_CODE (type) == ARRAY_TYPE)
4627 type = TREE_TYPE (type);
4629 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4630 align = MAX (align, 64);
4636 /* Darwin increases record alignment to the natural alignment of
4640 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4641 unsigned int specified)
4643 unsigned int align = MAX (computed, specified);
4645 if (TYPE_PACKED (type))
4648 /* Find the first field, looking down into aggregates. */
4650 tree field = TYPE_FIELDS (type);
4651 /* Skip all non field decls */
4652 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4653 field = TREE_CHAIN (field);
4656 /* A packed field does not contribute any extra alignment. */
4657 if (DECL_PACKED (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);
5302 && GET_CODE (orig_x) == LO_SUM
5303 && GET_CODE (XEXP (x, 1)) == CONST)
5305 y = XEXP (XEXP (x, 1), 0);
5306 if (GET_CODE (y) == UNSPEC
5307 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5308 return XVECEXP (y, 0, 0);
5314 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5316 static GTY(()) rtx rs6000_tls_symbol;
5318 rs6000_tls_get_addr (void)
5320 if (!rs6000_tls_symbol)
5321 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5323 return rs6000_tls_symbol;
5326 /* Construct the SYMBOL_REF for TLS GOT references. */
5328 static GTY(()) rtx rs6000_got_symbol;
5330 rs6000_got_sym (void)
5332 if (!rs6000_got_symbol)
5334 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5335 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5336 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5339 return rs6000_got_symbol;
5342 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5343 this (thread-local) address. */
5346 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5350 dest = gen_reg_rtx (Pmode);
5351 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5357 tlsreg = gen_rtx_REG (Pmode, 13);
5358 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5362 tlsreg = gen_rtx_REG (Pmode, 2);
5363 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5367 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5371 tmp = gen_reg_rtx (Pmode);
5374 tlsreg = gen_rtx_REG (Pmode, 13);
5375 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5379 tlsreg = gen_rtx_REG (Pmode, 2);
5380 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5384 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5386 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5391 rtx r3, got, tga, tmp1, tmp2, eqv;
5393 /* We currently use relocations like @got@tlsgd for tls, which
5394 means the linker will handle allocation of tls entries, placing
5395 them in the .got section. So use a pointer to the .got section,
5396 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5397 or to secondary GOT sections used by 32-bit -fPIC. */
5399 got = gen_rtx_REG (Pmode, 2);
5403 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5406 rtx gsym = rs6000_got_sym ();
5407 got = gen_reg_rtx (Pmode);
5409 rs6000_emit_move (got, gsym, Pmode);
5415 tmp1 = gen_reg_rtx (Pmode);
5416 tmp2 = gen_reg_rtx (Pmode);
5417 tmp3 = gen_reg_rtx (Pmode);
5418 mem = gen_const_mem (Pmode, tmp1);
5420 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5421 emit_move_insn (tmp1,
5422 gen_rtx_REG (Pmode, LR_REGNO));
5423 emit_move_insn (tmp2, mem);
5424 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5425 last = emit_move_insn (got, tmp3);
5426 set_unique_reg_note (last, REG_EQUAL, gsym);
5431 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5433 r3 = gen_rtx_REG (Pmode, 3);
5434 tga = rs6000_tls_get_addr ();
5436 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5437 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5438 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5439 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5440 else if (DEFAULT_ABI == ABI_V4)
5441 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5446 insn = emit_call_insn (insn);
5447 RTL_CONST_CALL_P (insn) = 1;
5448 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5449 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5450 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5451 insn = get_insns ();
5453 emit_libcall_block (insn, dest, r3, addr);
5455 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5457 r3 = gen_rtx_REG (Pmode, 3);
5458 tga = rs6000_tls_get_addr ();
5460 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5461 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5462 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5463 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5464 else if (DEFAULT_ABI == ABI_V4)
5465 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5470 insn = emit_call_insn (insn);
5471 RTL_CONST_CALL_P (insn) = 1;
5472 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5473 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5474 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5475 insn = get_insns ();
5477 tmp1 = gen_reg_rtx (Pmode);
5478 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5480 emit_libcall_block (insn, tmp1, r3, eqv);
5481 if (rs6000_tls_size == 16)
5484 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5486 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5488 else if (rs6000_tls_size == 32)
5490 tmp2 = gen_reg_rtx (Pmode);
5492 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5494 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5497 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5499 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5503 tmp2 = gen_reg_rtx (Pmode);
5505 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5507 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5509 insn = gen_rtx_SET (Pmode, dest,
5510 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5516 /* IE, or 64-bit offset LE. */
5517 tmp2 = gen_reg_rtx (Pmode);
5519 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5521 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5524 insn = gen_tls_tls_64 (dest, tmp2, addr);
5526 insn = gen_tls_tls_32 (dest, tmp2, addr);
5534 /* Return 1 if X contains a thread-local symbol. */
5537 rs6000_tls_referenced_p (rtx x)
5539 if (! TARGET_HAVE_TLS)
5542 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5545 /* Return 1 if *X is a thread-local symbol. This is the same as
5546 rs6000_tls_symbol_ref except for the type of the unused argument. */
5549 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5551 return RS6000_SYMBOL_REF_TLS_P (*x);
5554 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5555 replace the input X, or the original X if no replacement is called for.
5556 The output parameter *WIN is 1 if the calling macro should goto WIN,
5559 For RS/6000, we wish to handle large displacements off a base
5560 register by splitting the addend across an addiu/addis and the mem insn.
5561 This cuts number of extra insns needed from 3 to 1.
5563 On Darwin, we use this to generate code for floating point constants.
5564 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5565 The Darwin code is inside #if TARGET_MACHO because only then are the
5566 machopic_* functions defined. */
5568 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5569 int opnum, int type,
5570 int ind_levels ATTRIBUTE_UNUSED, int *win)
5572 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5574 /* We must recognize output that we have already generated ourselves. */
5575 if (GET_CODE (x) == PLUS
5576 && GET_CODE (XEXP (x, 0)) == PLUS
5577 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5578 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5579 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5581 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5582 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5583 opnum, (enum reload_type)type);
5589 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5590 && GET_CODE (x) == LO_SUM
5591 && GET_CODE (XEXP (x, 0)) == PLUS
5592 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5593 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5594 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5595 && machopic_operand_p (XEXP (x, 1)))
5597 /* Result of previous invocation of this function on Darwin
5598 floating point constant. */
5599 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5600 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5601 opnum, (enum reload_type)type);
5607 /* Force ld/std non-word aligned offset into base register by wrapping
5609 if (GET_CODE (x) == PLUS
5610 && GET_CODE (XEXP (x, 0)) == REG
5611 && REGNO (XEXP (x, 0)) < 32
5612 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5613 && GET_CODE (XEXP (x, 1)) == CONST_INT
5615 && (INTVAL (XEXP (x, 1)) & 3) != 0
5616 && VECTOR_MEM_NONE_P (mode)
5617 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5618 && TARGET_POWERPC64)
5620 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5621 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5622 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5623 opnum, (enum reload_type) type);
5628 if (GET_CODE (x) == PLUS
5629 && GET_CODE (XEXP (x, 0)) == REG
5630 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5631 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5632 && GET_CODE (XEXP (x, 1)) == CONST_INT
5634 && !SPE_VECTOR_MODE (mode)
5635 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5636 || mode == DDmode || mode == TDmode
5638 && VECTOR_MEM_NONE_P (mode))
5640 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5641 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5643 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5645 /* Check for 32-bit overflow. */
5646 if (high + low != val)
5652 /* Reload the high part into a base reg; leave the low part
5653 in the mem directly. */
5655 x = gen_rtx_PLUS (GET_MODE (x),
5656 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5660 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5661 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5662 opnum, (enum reload_type)type);
5667 if (GET_CODE (x) == SYMBOL_REF
5669 && VECTOR_MEM_NONE_P (mode)
5670 && !SPE_VECTOR_MODE (mode)
5672 && DEFAULT_ABI == ABI_DARWIN
5673 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5675 && DEFAULT_ABI == ABI_V4
5678 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5679 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5683 && (mode != DImode || TARGET_POWERPC64)
5684 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5685 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5690 rtx offset = machopic_gen_offset (x);
5691 x = gen_rtx_LO_SUM (GET_MODE (x),
5692 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5693 gen_rtx_HIGH (Pmode, offset)), offset);
5697 x = gen_rtx_LO_SUM (GET_MODE (x),
5698 gen_rtx_HIGH (Pmode, x), x);
5700 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5701 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5702 opnum, (enum reload_type)type);
5707 /* Reload an offset address wrapped by an AND that represents the
5708 masking of the lower bits. Strip the outer AND and let reload
5709 convert the offset address into an indirect address. For VSX,
5710 force reload to create the address with an AND in a separate
5711 register, because we can't guarantee an altivec register will
5713 if (VECTOR_MEM_ALTIVEC_P (mode)
5714 && GET_CODE (x) == AND
5715 && GET_CODE (XEXP (x, 0)) == PLUS
5716 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5717 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5718 && GET_CODE (XEXP (x, 1)) == CONST_INT
5719 && INTVAL (XEXP (x, 1)) == -16)
5728 && GET_CODE (x) == SYMBOL_REF
5729 && constant_pool_expr_p (x)
5730 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5732 x = create_TOC_reference (x);
5740 /* Debug version of rs6000_legitimize_reload_address. */
5742 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5743 int opnum, int type,
5744 int ind_levels, int *win)
5746 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5749 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5750 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5751 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5755 fprintf (stderr, "Same address returned\n");
5757 fprintf (stderr, "NULL returned\n");
5760 fprintf (stderr, "New address:\n");
5767 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5768 that is a valid memory address for an instruction.
5769 The MODE argument is the machine mode for the MEM expression
5770 that wants to use this address.
5772 On the RS/6000, there are four valid address: a SYMBOL_REF that
5773 refers to a constant pool entry of an address (or the sum of it
5774 plus a constant), a short (16-bit signed) constant plus a register,
5775 the sum of two registers, or a register indirect, possibly with an
5776 auto-increment. For DFmode, DDmode and DImode with a constant plus
5777 register, we must ensure that both words are addressable or PowerPC64
5778 with offset word aligned.
5780 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5781 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5782 because adjacent memory cells are accessed by adding word-sized offsets
5783 during assembly output. */
5785 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5787 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5789 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5790 if (VECTOR_MEM_ALTIVEC_P (mode)
5791 && GET_CODE (x) == AND
5792 && GET_CODE (XEXP (x, 1)) == CONST_INT
5793 && INTVAL (XEXP (x, 1)) == -16)
5796 if (RS6000_SYMBOL_REF_TLS_P (x))
5798 if (legitimate_indirect_address_p (x, reg_ok_strict))
5800 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5801 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5802 && !SPE_VECTOR_MODE (mode)
5805 /* Restrict addressing for DI because of our SUBREG hackery. */
5806 && !(TARGET_E500_DOUBLE
5807 && (mode == DFmode || mode == DDmode || mode == DImode))
5809 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5811 if (virtual_stack_registers_memory_p (x))
5813 if (reg_offset_p && legitimate_small_data_p (mode, x))
5815 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5817 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5820 && GET_CODE (x) == PLUS
5821 && GET_CODE (XEXP (x, 0)) == REG
5822 && (XEXP (x, 0) == virtual_stack_vars_rtx
5823 || XEXP (x, 0) == arg_pointer_rtx)
5824 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5826 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5831 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5833 || (mode != DFmode && mode != DDmode)
5834 || (TARGET_E500_DOUBLE && mode != DDmode))
5835 && (TARGET_POWERPC64 || mode != DImode)
5836 && !avoiding_indexed_address_p (mode)
5837 && legitimate_indexed_address_p (x, reg_ok_strict))
5839 if (GET_CODE (x) == PRE_MODIFY
5843 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5845 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5846 && (TARGET_POWERPC64 || mode != DImode)
5847 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5848 && !SPE_VECTOR_MODE (mode)
5849 /* Restrict addressing for DI because of our SUBREG hackery. */
5850 && !(TARGET_E500_DOUBLE
5851 && (mode == DFmode || mode == DDmode || mode == DImode))
5853 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5854 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5855 || (!avoiding_indexed_address_p (mode)
5856 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5857 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5859 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5864 /* Debug version of rs6000_legitimate_address_p. */
5866 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5869 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5871 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5872 "strict = %d, code = %s\n",
5873 ret ? "true" : "false",
5874 GET_MODE_NAME (mode),
5876 GET_RTX_NAME (GET_CODE (x)));
5882 /* Go to LABEL if ADDR (a legitimate address expression)
5883 has an effect that depends on the machine mode it is used for.
5885 On the RS/6000 this is true of all integral offsets (since AltiVec
5886 and VSX modes don't allow them) or is a pre-increment or decrement.
5888 ??? Except that due to conceptual problems in offsettable_address_p
5889 we can't really report the problems of integral offsets. So leave
5890 this assuming that the adjustable offset must be valid for the
5891 sub-words of a TFmode operand, which is what we had before. */
5894 rs6000_mode_dependent_address (rtx addr)
5896 switch (GET_CODE (addr))
5899 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5900 is considered a legitimate address before reload, so there
5901 are no offset restrictions in that case. Note that this
5902 condition is safe in strict mode because any address involving
5903 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5904 been rejected as illegitimate. */
5905 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5906 && XEXP (addr, 0) != arg_pointer_rtx
5907 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5909 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5910 return val + 12 + 0x8000 >= 0x10000;
5917 /* Auto-increment cases are now treated generically in recog.c. */
5919 return TARGET_UPDATE;
5921 /* AND is only allowed in Altivec loads. */
5932 /* Debug version of rs6000_mode_dependent_address. */
5934 rs6000_debug_mode_dependent_address (rtx addr)
5936 bool ret = rs6000_mode_dependent_address (addr);
5938 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5939 ret ? "true" : "false");
5945 /* Implement FIND_BASE_TERM. */
5948 rs6000_find_base_term (rtx op)
5952 split_const (op, &base, &offset);
5953 if (GET_CODE (base) == UNSPEC)
5954 switch (XINT (base, 1))
5957 case UNSPEC_MACHOPIC_OFFSET:
5958 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5959 for aliasing purposes. */
5960 return XVECEXP (base, 0, 0);
5966 /* More elaborate version of recog's offsettable_memref_p predicate
5967 that works around the ??? note of rs6000_mode_dependent_address.
5968 In particular it accepts
5970 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5972 in 32-bit mode, that the recog predicate rejects. */
5975 rs6000_offsettable_memref_p (rtx op)
5980 /* First mimic offsettable_memref_p. */
5981 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5984 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5985 the latter predicate knows nothing about the mode of the memory
5986 reference and, therefore, assumes that it is the largest supported
5987 mode (TFmode). As a consequence, legitimate offsettable memory
5988 references are rejected. rs6000_legitimate_offset_address_p contains
5989 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5990 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5993 /* Change register usage conditional on target flags. */
5995 rs6000_conditional_register_usage (void)
5999 /* Set MQ register fixed (already call_used) if not POWER
6000 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6005 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6007 fixed_regs[13] = call_used_regs[13]
6008 = call_really_used_regs[13] = 1;
6010 /* Conditionally disable FPRs. */
6011 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6012 for (i = 32; i < 64; i++)
6013 fixed_regs[i] = call_used_regs[i]
6014 = call_really_used_regs[i] = 1;
6016 /* The TOC register is not killed across calls in a way that is
6017 visible to the compiler. */
6018 if (DEFAULT_ABI == ABI_AIX)
6019 call_really_used_regs[2] = 0;
6021 if (DEFAULT_ABI == ABI_V4
6022 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6024 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6026 if (DEFAULT_ABI == ABI_V4
6027 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6029 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6030 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6031 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6033 if (DEFAULT_ABI == ABI_DARWIN
6034 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6035 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6036 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6037 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6039 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6040 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6041 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6045 global_regs[SPEFSCR_REGNO] = 1;
6046 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6047 registers in prologues and epilogues. We no longer use r14
6048 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6049 pool for link-compatibility with older versions of GCC. Once
6050 "old" code has died out, we can return r14 to the allocation
6053 = call_used_regs[14]
6054 = call_really_used_regs[14] = 1;
6057 if (!TARGET_ALTIVEC && !TARGET_VSX)
6059 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6060 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6061 call_really_used_regs[VRSAVE_REGNO] = 1;
6064 if (TARGET_ALTIVEC || TARGET_VSX)
6065 global_regs[VSCR_REGNO] = 1;
6067 if (TARGET_ALTIVEC_ABI)
6069 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6070 call_used_regs[i] = call_really_used_regs[i] = 1;
6072 /* AIX reserves VR20:31 in non-extended ABI mode. */
6074 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6075 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6079 /* Try to output insns to set TARGET equal to the constant C if it can
6080 be done in less than N insns. Do all computations in MODE.
6081 Returns the place where the output has been placed if it can be
6082 done and the insns have been emitted. If it would take more than N
6083 insns, zero is returned and no insns and emitted. */
6086 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6087 rtx source, int n ATTRIBUTE_UNUSED)
6089 rtx result, insn, set;
6090 HOST_WIDE_INT c0, c1;
6097 dest = gen_reg_rtx (mode);
6098 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6102 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6104 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6105 GEN_INT (INTVAL (source)
6106 & (~ (HOST_WIDE_INT) 0xffff))));
6107 emit_insn (gen_rtx_SET (VOIDmode, dest,
6108 gen_rtx_IOR (SImode, copy_rtx (result),
6109 GEN_INT (INTVAL (source) & 0xffff))));
6114 switch (GET_CODE (source))
6117 c0 = INTVAL (source);
6122 #if HOST_BITS_PER_WIDE_INT >= 64
6123 c0 = CONST_DOUBLE_LOW (source);
6126 c0 = CONST_DOUBLE_LOW (source);
6127 c1 = CONST_DOUBLE_HIGH (source);
6135 result = rs6000_emit_set_long_const (dest, c0, c1);
6142 insn = get_last_insn ();
6143 set = single_set (insn);
6144 if (! CONSTANT_P (SET_SRC (set)))
6145 set_unique_reg_note (insn, REG_EQUAL, source);
6150 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6151 fall back to a straight forward decomposition. We do this to avoid
6152 exponential run times encountered when looking for longer sequences
6153 with rs6000_emit_set_const. */
6155 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6157 if (!TARGET_POWERPC64)
6159 rtx operand1, operand2;
6161 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6163 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6165 emit_move_insn (operand1, GEN_INT (c1));
6166 emit_move_insn (operand2, GEN_INT (c2));
6170 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6173 ud2 = (c1 & 0xffff0000) >> 16;
6174 #if HOST_BITS_PER_WIDE_INT >= 64
6178 ud4 = (c2 & 0xffff0000) >> 16;
6180 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6181 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6184 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6186 emit_move_insn (dest, GEN_INT (ud1));
6189 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6190 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6193 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6196 emit_move_insn (dest, GEN_INT (ud2 << 16));
6198 emit_move_insn (copy_rtx (dest),
6199 gen_rtx_IOR (DImode, copy_rtx (dest),
6202 else if (ud3 == 0 && ud4 == 0)
6204 gcc_assert (ud2 & 0x8000);
6205 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6208 emit_move_insn (copy_rtx (dest),
6209 gen_rtx_IOR (DImode, copy_rtx (dest),
6211 emit_move_insn (copy_rtx (dest),
6212 gen_rtx_ZERO_EXTEND (DImode,
6213 gen_lowpart (SImode,
6216 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6217 || (ud4 == 0 && ! (ud3 & 0x8000)))
6220 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6223 emit_move_insn (dest, GEN_INT (ud3 << 16));
6226 emit_move_insn (copy_rtx (dest),
6227 gen_rtx_IOR (DImode, copy_rtx (dest),
6229 emit_move_insn (copy_rtx (dest),
6230 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6233 emit_move_insn (copy_rtx (dest),
6234 gen_rtx_IOR (DImode, copy_rtx (dest),
6240 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6243 emit_move_insn (dest, GEN_INT (ud4 << 16));
6246 emit_move_insn (copy_rtx (dest),
6247 gen_rtx_IOR (DImode, copy_rtx (dest),
6250 emit_move_insn (copy_rtx (dest),
6251 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6254 emit_move_insn (copy_rtx (dest),
6255 gen_rtx_IOR (DImode, copy_rtx (dest),
6256 GEN_INT (ud2 << 16)));
6258 emit_move_insn (copy_rtx (dest),
6259 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6265 /* Helper for the following. Get rid of [r+r] memory refs
6266 in cases where it won't work (TImode, TFmode, TDmode). */
6269 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6271 if (GET_CODE (operands[0]) == MEM
6272 && GET_CODE (XEXP (operands[0], 0)) != REG
6273 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6274 && ! reload_in_progress)
6276 = replace_equiv_address (operands[0],
6277 copy_addr_to_reg (XEXP (operands[0], 0)));
6279 if (GET_CODE (operands[1]) == MEM
6280 && GET_CODE (XEXP (operands[1], 0)) != REG
6281 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6282 && ! reload_in_progress)
6284 = replace_equiv_address (operands[1],
6285 copy_addr_to_reg (XEXP (operands[1], 0)));
6288 /* Emit a move from SOURCE to DEST in mode MODE. */
6290 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6294 operands[1] = source;
6296 if (TARGET_DEBUG_ADDR)
6299 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6300 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6301 GET_MODE_NAME (mode),
6304 can_create_pseudo_p ());
6306 fprintf (stderr, "source:\n");
6310 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6311 if (GET_CODE (operands[1]) == CONST_DOUBLE
6312 && ! FLOAT_MODE_P (mode)
6313 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6315 /* FIXME. This should never happen. */
6316 /* Since it seems that it does, do the safe thing and convert
6318 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6320 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6321 || FLOAT_MODE_P (mode)
6322 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6323 || CONST_DOUBLE_LOW (operands[1]) < 0)
6324 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6325 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6327 /* Check if GCC is setting up a block move that will end up using FP
6328 registers as temporaries. We must make sure this is acceptable. */
6329 if (GET_CODE (operands[0]) == MEM
6330 && GET_CODE (operands[1]) == MEM
6332 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6333 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6334 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6335 ? 32 : MEM_ALIGN (operands[0])))
6336 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6338 : MEM_ALIGN (operands[1]))))
6339 && ! MEM_VOLATILE_P (operands [0])
6340 && ! MEM_VOLATILE_P (operands [1]))
6342 emit_move_insn (adjust_address (operands[0], SImode, 0),
6343 adjust_address (operands[1], SImode, 0));
6344 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6345 adjust_address (copy_rtx (operands[1]), SImode, 4));
6349 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6350 && !gpc_reg_operand (operands[1], mode))
6351 operands[1] = force_reg (mode, operands[1]);
6353 if (mode == SFmode && ! TARGET_POWERPC
6354 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6355 && GET_CODE (operands[0]) == MEM)
6359 if (reload_in_progress || reload_completed)
6360 regnum = true_regnum (operands[1]);
6361 else if (GET_CODE (operands[1]) == REG)
6362 regnum = REGNO (operands[1]);
6366 /* If operands[1] is a register, on POWER it may have
6367 double-precision data in it, so truncate it to single
6369 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6372 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6373 : gen_reg_rtx (mode));
6374 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6375 operands[1] = newreg;
6379 /* Recognize the case where operand[1] is a reference to thread-local
6380 data and load its address to a register. */
6381 if (rs6000_tls_referenced_p (operands[1]))
6383 enum tls_model model;
6384 rtx tmp = operands[1];
6387 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6389 addend = XEXP (XEXP (tmp, 0), 1);
6390 tmp = XEXP (XEXP (tmp, 0), 0);
6393 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6394 model = SYMBOL_REF_TLS_MODEL (tmp);
6395 gcc_assert (model != 0);
6397 tmp = rs6000_legitimize_tls_address (tmp, model);
6400 tmp = gen_rtx_PLUS (mode, tmp, addend);
6401 tmp = force_operand (tmp, operands[0]);
6406 /* Handle the case where reload calls us with an invalid address. */
6407 if (reload_in_progress && mode == Pmode
6408 && (! general_operand (operands[1], mode)
6409 || ! nonimmediate_operand (operands[0], mode)))
6412 /* 128-bit constant floating-point values on Darwin should really be
6413 loaded as two parts. */
6414 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6415 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6417 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6418 know how to get a DFmode SUBREG of a TFmode. */
6419 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6420 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6421 simplify_gen_subreg (imode, operands[1], mode, 0),
6423 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6424 GET_MODE_SIZE (imode)),
6425 simplify_gen_subreg (imode, operands[1], mode,
6426 GET_MODE_SIZE (imode)),
6431 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6432 cfun->machine->sdmode_stack_slot =
6433 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6435 if (reload_in_progress
6437 && MEM_P (operands[0])
6438 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6439 && REG_P (operands[1]))
6441 if (FP_REGNO_P (REGNO (operands[1])))
6443 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6444 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6445 emit_insn (gen_movsd_store (mem, operands[1]));
6447 else if (INT_REGNO_P (REGNO (operands[1])))
6449 rtx mem = adjust_address_nv (operands[0], mode, 4);
6450 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6451 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6457 if (reload_in_progress
6459 && REG_P (operands[0])
6460 && MEM_P (operands[1])
6461 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6463 if (FP_REGNO_P (REGNO (operands[0])))
6465 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6466 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6467 emit_insn (gen_movsd_load (operands[0], mem));
6469 else if (INT_REGNO_P (REGNO (operands[0])))
6471 rtx mem = adjust_address_nv (operands[1], mode, 4);
6472 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6473 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6480 /* FIXME: In the long term, this switch statement should go away
6481 and be replaced by a sequence of tests based on things like
6487 if (CONSTANT_P (operands[1])
6488 && GET_CODE (operands[1]) != CONST_INT)
6489 operands[1] = force_const_mem (mode, operands[1]);
6494 rs6000_eliminate_indexed_memrefs (operands);
6501 if (CONSTANT_P (operands[1])
6502 && ! easy_fp_constant (operands[1], mode))
6503 operands[1] = force_const_mem (mode, operands[1]);
6516 if (CONSTANT_P (operands[1])
6517 && !easy_vector_constant (operands[1], mode))
6518 operands[1] = force_const_mem (mode, operands[1]);
6523 /* Use default pattern for address of ELF small data */
6526 && DEFAULT_ABI == ABI_V4
6527 && (GET_CODE (operands[1]) == SYMBOL_REF
6528 || GET_CODE (operands[1]) == CONST)
6529 && small_data_operand (operands[1], mode))
6531 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6535 if (DEFAULT_ABI == ABI_V4
6536 && mode == Pmode && mode == SImode
6537 && flag_pic == 1 && got_operand (operands[1], mode))
6539 emit_insn (gen_movsi_got (operands[0], operands[1]));
6543 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6547 && CONSTANT_P (operands[1])
6548 && GET_CODE (operands[1]) != HIGH
6549 && GET_CODE (operands[1]) != CONST_INT)
6551 rtx target = (!can_create_pseudo_p ()
6553 : gen_reg_rtx (mode));
6555 /* If this is a function address on -mcall-aixdesc,
6556 convert it to the address of the descriptor. */
6557 if (DEFAULT_ABI == ABI_AIX
6558 && GET_CODE (operands[1]) == SYMBOL_REF
6559 && XSTR (operands[1], 0)[0] == '.')
6561 const char *name = XSTR (operands[1], 0);
6563 while (*name == '.')
6565 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6566 CONSTANT_POOL_ADDRESS_P (new_ref)
6567 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6568 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6569 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6570 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6571 operands[1] = new_ref;
6574 if (DEFAULT_ABI == ABI_DARWIN)
6577 if (MACHO_DYNAMIC_NO_PIC_P)
6579 /* Take care of any required data indirection. */
6580 operands[1] = rs6000_machopic_legitimize_pic_address (
6581 operands[1], mode, operands[0]);
6582 if (operands[0] != operands[1])
6583 emit_insn (gen_rtx_SET (VOIDmode,
6584 operands[0], operands[1]));
6588 emit_insn (gen_macho_high (target, operands[1]));
6589 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6593 emit_insn (gen_elf_high (target, operands[1]));
6594 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6598 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6599 and we have put it in the TOC, we just need to make a TOC-relative
6602 && GET_CODE (operands[1]) == SYMBOL_REF
6603 && constant_pool_expr_p (operands[1])
6604 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6605 get_pool_mode (operands[1])))
6607 operands[1] = create_TOC_reference (operands[1]);
6609 else if (mode == Pmode
6610 && CONSTANT_P (operands[1])
6611 && ((GET_CODE (operands[1]) != CONST_INT
6612 && ! easy_fp_constant (operands[1], mode))
6613 || (GET_CODE (operands[1]) == CONST_INT
6614 && num_insns_constant (operands[1], mode) > 2)
6615 || (GET_CODE (operands[0]) == REG
6616 && FP_REGNO_P (REGNO (operands[0]))))
6617 && GET_CODE (operands[1]) != HIGH
6618 && ! legitimate_constant_pool_address_p (operands[1])
6619 && ! toc_relative_expr_p (operands[1]))
6623 /* Darwin uses a special PIC legitimizer. */
6624 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6627 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6629 if (operands[0] != operands[1])
6630 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6635 /* If we are to limit the number of things we put in the TOC and
6636 this is a symbol plus a constant we can add in one insn,
6637 just put the symbol in the TOC and add the constant. Don't do
6638 this if reload is in progress. */
6639 if (GET_CODE (operands[1]) == CONST
6640 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6641 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6642 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6643 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6644 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6645 && ! side_effects_p (operands[0]))
6648 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6649 rtx other = XEXP (XEXP (operands[1], 0), 1);
6651 sym = force_reg (mode, sym);
6652 emit_insn (gen_add3_insn (operands[0], sym, other));
6656 operands[1] = force_const_mem (mode, operands[1]);
6659 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6660 && constant_pool_expr_p (XEXP (operands[1], 0))
6661 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6662 get_pool_constant (XEXP (operands[1], 0)),
6663 get_pool_mode (XEXP (operands[1], 0))))
6666 = gen_const_mem (mode,
6667 create_TOC_reference (XEXP (operands[1], 0)));
6668 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6674 rs6000_eliminate_indexed_memrefs (operands);
6678 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6680 gen_rtx_SET (VOIDmode,
6681 operands[0], operands[1]),
6682 gen_rtx_CLOBBER (VOIDmode,
6683 gen_rtx_SCRATCH (SImode)))));
6689 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6692 /* Above, we may have called force_const_mem which may have returned
6693 an invalid address. If we can, fix this up; otherwise, reload will
6694 have to deal with it. */
6695 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6696 operands[1] = validize_mem (operands[1]);
6699 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6702 /* Nonzero if we can use a floating-point register to pass this arg. */
6703 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6704 (SCALAR_FLOAT_MODE_P (MODE) \
6705 && (CUM)->fregno <= FP_ARG_MAX_REG \
6706 && TARGET_HARD_FLOAT && TARGET_FPRS)
6708 /* Nonzero if we can use an AltiVec register to pass this arg. */
6709 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6710 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6711 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6712 && TARGET_ALTIVEC_ABI \
6715 /* Return a nonzero value to say to return the function value in
6716 memory, just as large structures are always returned. TYPE will be
6717 the data type of the value, and FNTYPE will be the type of the
6718 function doing the returning, or @code{NULL} for libcalls.
6720 The AIX ABI for the RS/6000 specifies that all structures are
6721 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6722 specifies that structures <= 8 bytes are returned in r3/r4, but a
6723 draft put them in memory, and GCC used to implement the draft
6724 instead of the final standard. Therefore, aix_struct_return
6725 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6726 compatibility can change DRAFT_V4_STRUCT_RET to override the
6727 default, and -m switches get the final word. See
6728 rs6000_override_options for more details.
6730 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6731 long double support is enabled. These values are returned in memory.
6733 int_size_in_bytes returns -1 for variable size objects, which go in
6734 memory always. The cast to unsigned makes -1 > 8. */
6737 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6739 /* In the darwin64 abi, try to use registers for larger structs
6741 if (rs6000_darwin64_abi
6742 && TREE_CODE (type) == RECORD_TYPE
6743 && int_size_in_bytes (type) > 0)
6745 CUMULATIVE_ARGS valcum;
6749 valcum.fregno = FP_ARG_MIN_REG;
6750 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6751 /* Do a trial code generation as if this were going to be passed
6752 as an argument; if any part goes in memory, we return NULL. */
6753 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6756 /* Otherwise fall through to more conventional ABI rules. */
6759 if (AGGREGATE_TYPE_P (type)
6760 && (aix_struct_return
6761 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6764 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6765 modes only exist for GCC vector types if -maltivec. */
6766 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6767 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6770 /* Return synthetic vectors in memory. */
6771 if (TREE_CODE (type) == VECTOR_TYPE
6772 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6774 static bool warned_for_return_big_vectors = false;
6775 if (!warned_for_return_big_vectors)
6777 warning (0, "GCC vector returned by reference: "
6778 "non-standard ABI extension with no compatibility guarantee");
6779 warned_for_return_big_vectors = true;
6784 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6790 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6791 for a call to a function whose data type is FNTYPE.
6792 For a library call, FNTYPE is 0.
6794 For incoming args we set the number of arguments in the prototype large
6795 so we never return a PARALLEL. */
6798 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6799 rtx libname ATTRIBUTE_UNUSED, int incoming,
6800 int libcall, int n_named_args)
6802 static CUMULATIVE_ARGS zero_cumulative;
6804 *cum = zero_cumulative;
6806 cum->fregno = FP_ARG_MIN_REG;
6807 cum->vregno = ALTIVEC_ARG_MIN_REG;
6808 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6809 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6810 ? CALL_LIBCALL : CALL_NORMAL);
6811 cum->sysv_gregno = GP_ARG_MIN_REG;
6812 cum->stdarg = fntype
6813 && (TYPE_ARG_TYPES (fntype) != 0
6814 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6815 != void_type_node));
6817 cum->nargs_prototype = 0;
6818 if (incoming || cum->prototype)
6819 cum->nargs_prototype = n_named_args;
6821 /* Check for a longcall attribute. */
6822 if ((!fntype && rs6000_default_long_calls)
6824 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6825 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6826 cum->call_cookie |= CALL_LONG;
6828 if (TARGET_DEBUG_ARG)
6830 fprintf (stderr, "\ninit_cumulative_args:");
6833 tree ret_type = TREE_TYPE (fntype);
6834 fprintf (stderr, " ret code = %s,",
6835 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6838 if (cum->call_cookie & CALL_LONG)
6839 fprintf (stderr, " longcall,");
6841 fprintf (stderr, " proto = %d, nargs = %d\n",
6842 cum->prototype, cum->nargs_prototype);
6847 && TARGET_ALTIVEC_ABI
6848 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6850 error ("cannot return value in vector register because"
6851 " altivec instructions are disabled, use -maltivec"
6856 /* Return true if TYPE must be passed on the stack and not in registers. */
6859 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6861 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6862 return must_pass_in_stack_var_size (mode, type);
6864 return must_pass_in_stack_var_size_or_pad (mode, type);
6867 /* If defined, a C expression which determines whether, and in which
6868 direction, to pad out an argument with extra space. The value
6869 should be of type `enum direction': either `upward' to pad above
6870 the argument, `downward' to pad below, or `none' to inhibit
6873 For the AIX ABI structs are always stored left shifted in their
6877 function_arg_padding (enum machine_mode mode, const_tree type)
6879 #ifndef AGGREGATE_PADDING_FIXED
6880 #define AGGREGATE_PADDING_FIXED 0
6882 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6883 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6886 if (!AGGREGATE_PADDING_FIXED)
6888 /* GCC used to pass structures of the same size as integer types as
6889 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6890 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6891 passed padded downward, except that -mstrict-align further
6892 muddied the water in that multi-component structures of 2 and 4
6893 bytes in size were passed padded upward.
6895 The following arranges for best compatibility with previous
6896 versions of gcc, but removes the -mstrict-align dependency. */
6897 if (BYTES_BIG_ENDIAN)
6899 HOST_WIDE_INT size = 0;
6901 if (mode == BLKmode)
6903 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6904 size = int_size_in_bytes (type);
6907 size = GET_MODE_SIZE (mode);
6909 if (size == 1 || size == 2 || size == 4)
6915 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6917 if (type != 0 && AGGREGATE_TYPE_P (type))
6921 /* Fall back to the default. */
6922 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6925 /* If defined, a C expression that gives the alignment boundary, in bits,
6926 of an argument with the specified mode and type. If it is not defined,
6927 PARM_BOUNDARY is used for all arguments.
6929 V.4 wants long longs and doubles to be double word aligned. Just
6930 testing the mode size is a boneheaded way to do this as it means
6931 that other types such as complex int are also double word aligned.
6932 However, we're stuck with this because changing the ABI might break
6933 existing library interfaces.
6935 Doubleword align SPE vectors.
6936 Quadword align Altivec vectors.
6937 Quadword align large synthetic vector types. */
6940 function_arg_boundary (enum machine_mode mode, tree type)
6942 if (DEFAULT_ABI == ABI_V4
6943 && (GET_MODE_SIZE (mode) == 8
6944 || (TARGET_HARD_FLOAT
6946 && (mode == TFmode || mode == TDmode))))
6948 else if (SPE_VECTOR_MODE (mode)
6949 || (type && TREE_CODE (type) == VECTOR_TYPE
6950 && int_size_in_bytes (type) >= 8
6951 && int_size_in_bytes (type) < 16))
6953 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6954 || (type && TREE_CODE (type) == VECTOR_TYPE
6955 && int_size_in_bytes (type) >= 16))
6957 else if (rs6000_darwin64_abi && mode == BLKmode
6958 && type && TYPE_ALIGN (type) > 64)
6961 return PARM_BOUNDARY;
6964 /* For a function parm of MODE and TYPE, return the starting word in
6965 the parameter area. NWORDS of the parameter area are already used. */
6968 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6971 unsigned int parm_offset;
6973 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6974 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6975 return nwords + (-(parm_offset + nwords) & align);
6978 /* Compute the size (in words) of a function argument. */
6980 static unsigned long
6981 rs6000_arg_size (enum machine_mode mode, tree type)
6985 if (mode != BLKmode)
6986 size = GET_MODE_SIZE (mode);
6988 size = int_size_in_bytes (type);
6991 return (size + 3) >> 2;
6993 return (size + 7) >> 3;
6996 /* Use this to flush pending int fields. */
6999 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7000 HOST_WIDE_INT bitpos)
7002 unsigned int startbit, endbit;
7003 int intregs, intoffset;
7004 enum machine_mode mode;
7006 if (cum->intoffset == -1)
7009 intoffset = cum->intoffset;
7010 cum->intoffset = -1;
7012 if (intoffset % BITS_PER_WORD != 0)
7014 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7016 if (mode == BLKmode)
7018 /* We couldn't find an appropriate mode, which happens,
7019 e.g., in packed structs when there are 3 bytes to load.
7020 Back intoffset back to the beginning of the word in this
7022 intoffset = intoffset & -BITS_PER_WORD;
7026 startbit = intoffset & -BITS_PER_WORD;
7027 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7028 intregs = (endbit - startbit) / BITS_PER_WORD;
7029 cum->words += intregs;
7032 /* The darwin64 ABI calls for us to recurse down through structs,
7033 looking for elements passed in registers. Unfortunately, we have
7034 to track int register count here also because of misalignments
7035 in powerpc alignment mode. */
7038 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7040 HOST_WIDE_INT startbitpos)
7044 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7045 if (TREE_CODE (f) == FIELD_DECL)
7047 HOST_WIDE_INT bitpos = startbitpos;
7048 tree ftype = TREE_TYPE (f);
7049 enum machine_mode mode;
7050 if (ftype == error_mark_node)
7052 mode = TYPE_MODE (ftype);
7054 if (DECL_SIZE (f) != 0
7055 && host_integerp (bit_position (f), 1))
7056 bitpos += int_bit_position (f);
7058 /* ??? FIXME: else assume zero offset. */
7060 if (TREE_CODE (ftype) == RECORD_TYPE)
7061 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7062 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7064 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7065 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7066 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7068 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7070 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7074 else if (cum->intoffset == -1)
7075 cum->intoffset = bitpos;
7079 /* Update the data in CUM to advance over an argument
7080 of mode MODE and data type TYPE.
7081 (TYPE is null for libcalls where that information may not be available.)
7083 Note that for args passed by reference, function_arg will be called
7084 with MODE and TYPE set to that of the pointer to the arg, not the arg
7088 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7089 tree type, int named, int depth)
7093 /* Only tick off an argument if we're not recursing. */
7095 cum->nargs_prototype--;
7097 if (TARGET_ALTIVEC_ABI
7098 && (ALTIVEC_VECTOR_MODE (mode)
7099 || VSX_VECTOR_MODE (mode)
7100 || (type && TREE_CODE (type) == VECTOR_TYPE
7101 && int_size_in_bytes (type) == 16)))
7105 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7108 if (!TARGET_ALTIVEC)
7109 error ("cannot pass argument in vector register because"
7110 " altivec instructions are disabled, use -maltivec"
7113 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7114 even if it is going to be passed in a vector register.
7115 Darwin does the same for variable-argument functions. */
7116 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7117 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7127 /* Vector parameters must be 16-byte aligned. This places
7128 them at 2 mod 4 in terms of words in 32-bit mode, since
7129 the parameter save area starts at offset 24 from the
7130 stack. In 64-bit mode, they just have to start on an
7131 even word, since the parameter save area is 16-byte
7132 aligned. Space for GPRs is reserved even if the argument
7133 will be passed in memory. */
7135 align = (2 - cum->words) & 3;
7137 align = cum->words & 1;
7138 cum->words += align + rs6000_arg_size (mode, type);
7140 if (TARGET_DEBUG_ARG)
7142 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7144 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7145 cum->nargs_prototype, cum->prototype,
7146 GET_MODE_NAME (mode));
7150 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7152 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7155 else if (rs6000_darwin64_abi
7157 && TREE_CODE (type) == RECORD_TYPE
7158 && (size = int_size_in_bytes (type)) > 0)
7160 /* Variable sized types have size == -1 and are
7161 treated as if consisting entirely of ints.
7162 Pad to 16 byte boundary if needed. */
7163 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7164 && (cum->words % 2) != 0)
7166 /* For varargs, we can just go up by the size of the struct. */
7168 cum->words += (size + 7) / 8;
7171 /* It is tempting to say int register count just goes up by
7172 sizeof(type)/8, but this is wrong in a case such as
7173 { int; double; int; } [powerpc alignment]. We have to
7174 grovel through the fields for these too. */
7176 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7177 rs6000_darwin64_record_arg_advance_flush (cum,
7178 size * BITS_PER_UNIT);
7181 else if (DEFAULT_ABI == ABI_V4)
7183 if (TARGET_HARD_FLOAT && TARGET_FPRS
7184 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7185 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7186 || (mode == TFmode && !TARGET_IEEEQUAD)
7187 || mode == SDmode || mode == DDmode || mode == TDmode))
7189 /* _Decimal128 must use an even/odd register pair. This assumes
7190 that the register number is odd when fregno is odd. */
7191 if (mode == TDmode && (cum->fregno % 2) == 1)
7194 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7195 <= FP_ARG_V4_MAX_REG)
7196 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7199 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7200 if (mode == DFmode || mode == TFmode
7201 || mode == DDmode || mode == TDmode)
7202 cum->words += cum->words & 1;
7203 cum->words += rs6000_arg_size (mode, type);
7208 int n_words = rs6000_arg_size (mode, type);
7209 int gregno = cum->sysv_gregno;
7211 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7212 (r7,r8) or (r9,r10). As does any other 2 word item such
7213 as complex int due to a historical mistake. */
7215 gregno += (1 - gregno) & 1;
7217 /* Multi-reg args are not split between registers and stack. */
7218 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7220 /* Long long and SPE vectors are aligned on the stack.
7221 So are other 2 word items such as complex int due to
7222 a historical mistake. */
7224 cum->words += cum->words & 1;
7225 cum->words += n_words;
7228 /* Note: continuing to accumulate gregno past when we've started
7229 spilling to the stack indicates the fact that we've started
7230 spilling to the stack to expand_builtin_saveregs. */
7231 cum->sysv_gregno = gregno + n_words;
7234 if (TARGET_DEBUG_ARG)
7236 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7237 cum->words, cum->fregno);
7238 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7239 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7240 fprintf (stderr, "mode = %4s, named = %d\n",
7241 GET_MODE_NAME (mode), named);
7246 int n_words = rs6000_arg_size (mode, type);
7247 int start_words = cum->words;
7248 int align_words = rs6000_parm_start (mode, type, start_words);
7250 cum->words = align_words + n_words;
7252 if (SCALAR_FLOAT_MODE_P (mode)
7253 && TARGET_HARD_FLOAT && TARGET_FPRS)
7255 /* _Decimal128 must be passed in an even/odd float register pair.
7256 This assumes that the register number is odd when fregno is
7258 if (mode == TDmode && (cum->fregno % 2) == 1)
7260 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7263 if (TARGET_DEBUG_ARG)
7265 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7266 cum->words, cum->fregno);
7267 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7268 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7269 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7270 named, align_words - start_words, depth);
7276 spe_build_register_parallel (enum machine_mode mode, int gregno)
7283 r1 = gen_rtx_REG (DImode, gregno);
7284 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7285 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7289 r1 = gen_rtx_REG (DImode, gregno);
7290 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7291 r3 = gen_rtx_REG (DImode, gregno + 2);
7292 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7293 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7296 r1 = gen_rtx_REG (DImode, gregno);
7297 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7298 r3 = gen_rtx_REG (DImode, gregno + 2);
7299 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7300 r5 = gen_rtx_REG (DImode, gregno + 4);
7301 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7302 r7 = gen_rtx_REG (DImode, gregno + 6);
7303 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7304 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7311 /* Determine where to put a SIMD argument on the SPE. */
7313 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7316 int gregno = cum->sysv_gregno;
7318 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7319 are passed and returned in a pair of GPRs for ABI compatibility. */
7320 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7321 || mode == DCmode || mode == TCmode))
7323 int n_words = rs6000_arg_size (mode, type);
7325 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7327 gregno += (1 - gregno) & 1;
7329 /* Multi-reg args are not split between registers and stack. */
7330 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7333 return spe_build_register_parallel (mode, gregno);
7337 int n_words = rs6000_arg_size (mode, type);
7339 /* SPE vectors are put in odd registers. */
7340 if (n_words == 2 && (gregno & 1) == 0)
7343 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7346 enum machine_mode m = SImode;
7348 r1 = gen_rtx_REG (m, gregno);
7349 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7350 r2 = gen_rtx_REG (m, gregno + 1);
7351 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7352 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7359 if (gregno <= GP_ARG_MAX_REG)
7360 return gen_rtx_REG (mode, gregno);
7366 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7367 structure between cum->intoffset and bitpos to integer registers. */
7370 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7371 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7373 enum machine_mode mode;
7375 unsigned int startbit, endbit;
7376 int this_regno, intregs, intoffset;
7379 if (cum->intoffset == -1)
7382 intoffset = cum->intoffset;
7383 cum->intoffset = -1;
7385 /* If this is the trailing part of a word, try to only load that
7386 much into the register. Otherwise load the whole register. Note
7387 that in the latter case we may pick up unwanted bits. It's not a
7388 problem at the moment but may wish to revisit. */
7390 if (intoffset % BITS_PER_WORD != 0)
7392 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7394 if (mode == BLKmode)
7396 /* We couldn't find an appropriate mode, which happens,
7397 e.g., in packed structs when there are 3 bytes to load.
7398 Back intoffset back to the beginning of the word in this
7400 intoffset = intoffset & -BITS_PER_WORD;
7407 startbit = intoffset & -BITS_PER_WORD;
7408 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7409 intregs = (endbit - startbit) / BITS_PER_WORD;
7410 this_regno = cum->words + intoffset / BITS_PER_WORD;
7412 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7415 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7419 intoffset /= BITS_PER_UNIT;
7422 regno = GP_ARG_MIN_REG + this_regno;
7423 reg = gen_rtx_REG (mode, regno);
7425 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7428 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7432 while (intregs > 0);
7435 /* Recursive workhorse for the following. */
7438 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7439 HOST_WIDE_INT startbitpos, rtx rvec[],
7444 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7445 if (TREE_CODE (f) == FIELD_DECL)
7447 HOST_WIDE_INT bitpos = startbitpos;
7448 tree ftype = TREE_TYPE (f);
7449 enum machine_mode mode;
7450 if (ftype == error_mark_node)
7452 mode = TYPE_MODE (ftype);
7454 if (DECL_SIZE (f) != 0
7455 && host_integerp (bit_position (f), 1))
7456 bitpos += int_bit_position (f);
7458 /* ??? FIXME: else assume zero offset. */
7460 if (TREE_CODE (ftype) == RECORD_TYPE)
7461 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7462 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7467 case SCmode: mode = SFmode; break;
7468 case DCmode: mode = DFmode; break;
7469 case TCmode: mode = TFmode; break;
7473 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7475 = gen_rtx_EXPR_LIST (VOIDmode,
7476 gen_rtx_REG (mode, cum->fregno++),
7477 GEN_INT (bitpos / BITS_PER_UNIT));
7478 if (mode == TFmode || mode == TDmode)
7481 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7483 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7485 = gen_rtx_EXPR_LIST (VOIDmode,
7486 gen_rtx_REG (mode, cum->vregno++),
7487 GEN_INT (bitpos / BITS_PER_UNIT));
7489 else if (cum->intoffset == -1)
7490 cum->intoffset = bitpos;
7494 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7495 the register(s) to be used for each field and subfield of a struct
7496 being passed by value, along with the offset of where the
7497 register's value may be found in the block. FP fields go in FP
7498 register, vector fields go in vector registers, and everything
7499 else goes in int registers, packed as in memory.
7501 This code is also used for function return values. RETVAL indicates
7502 whether this is the case.
7504 Much of this is taken from the SPARC V9 port, which has a similar
7505 calling convention. */
7508 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7509 int named, bool retval)
7511 rtx rvec[FIRST_PSEUDO_REGISTER];
7512 int k = 1, kbase = 1;
7513 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7514 /* This is a copy; modifications are not visible to our caller. */
7515 CUMULATIVE_ARGS copy_cum = *orig_cum;
7516 CUMULATIVE_ARGS *cum = ©_cum;
7518 /* Pad to 16 byte boundary if needed. */
7519 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7520 && (cum->words % 2) != 0)
7527 /* Put entries into rvec[] for individual FP and vector fields, and
7528 for the chunks of memory that go in int regs. Note we start at
7529 element 1; 0 is reserved for an indication of using memory, and
7530 may or may not be filled in below. */
7531 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7532 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7534 /* If any part of the struct went on the stack put all of it there.
7535 This hack is because the generic code for
7536 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7537 parts of the struct are not at the beginning. */
7541 return NULL_RTX; /* doesn't go in registers at all */
7543 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7545 if (k > 1 || cum->use_stack)
7546 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7551 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7554 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7558 rtx rvec[GP_ARG_NUM_REG + 1];
7560 if (align_words >= GP_ARG_NUM_REG)
7563 n_units = rs6000_arg_size (mode, type);
7565 /* Optimize the simple case where the arg fits in one gpr, except in
7566 the case of BLKmode due to assign_parms assuming that registers are
7567 BITS_PER_WORD wide. */
7569 || (n_units == 1 && mode != BLKmode))
7570 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7573 if (align_words + n_units > GP_ARG_NUM_REG)
7574 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7575 using a magic NULL_RTX component.
7576 This is not strictly correct. Only some of the arg belongs in
7577 memory, not all of it. However, the normal scheme using
7578 function_arg_partial_nregs can result in unusual subregs, eg.
7579 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7580 store the whole arg to memory is often more efficient than code
7581 to store pieces, and we know that space is available in the right
7582 place for the whole arg. */
7583 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7588 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7589 rtx off = GEN_INT (i++ * 4);
7590 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7592 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7594 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7597 /* Determine where to put an argument to a function.
7598 Value is zero to push the argument on the stack,
7599 or a hard register in which to store the argument.
7601 MODE is the argument's machine mode.
7602 TYPE is the data type of the argument (as a tree).
7603 This is null for libcalls where that information may
7605 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7606 the preceding args and about the function being called. It is
7607 not modified in this routine.
7608 NAMED is nonzero if this argument is a named parameter
7609 (otherwise it is an extra parameter matching an ellipsis).
7611 On RS/6000 the first eight words of non-FP are normally in registers
7612 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7613 Under V.4, the first 8 FP args are in registers.
7615 If this is floating-point and no prototype is specified, we use
7616 both an FP and integer register (or possibly FP reg and stack). Library
7617 functions (when CALL_LIBCALL is set) always have the proper types for args,
7618 so we can pass the FP value just in one register. emit_library_function
7619 doesn't support PARALLEL anyway.
7621 Note that for args passed by reference, function_arg will be called
7622 with MODE and TYPE set to that of the pointer to the arg, not the arg
7626 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7627 tree type, int named)
7629 enum rs6000_abi abi = DEFAULT_ABI;
7631 /* Return a marker to indicate whether CR1 needs to set or clear the
7632 bit that V.4 uses to say fp args were passed in registers.
7633 Assume that we don't need the marker for software floating point,
7634 or compiler generated library calls. */
7635 if (mode == VOIDmode)
7638 && (cum->call_cookie & CALL_LIBCALL) == 0
7640 || (cum->nargs_prototype < 0
7641 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7643 /* For the SPE, we need to crxor CR6 always. */
7645 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7646 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7647 return GEN_INT (cum->call_cookie
7648 | ((cum->fregno == FP_ARG_MIN_REG)
7649 ? CALL_V4_SET_FP_ARGS
7650 : CALL_V4_CLEAR_FP_ARGS));
7653 return GEN_INT (cum->call_cookie);
7656 if (rs6000_darwin64_abi && mode == BLKmode
7657 && TREE_CODE (type) == RECORD_TYPE)
7659 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7660 if (rslt != NULL_RTX)
7662 /* Else fall through to usual handling. */
7665 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7666 if (TARGET_64BIT && ! cum->prototype)
7668 /* Vector parameters get passed in vector register
7669 and also in GPRs or memory, in absence of prototype. */
7672 align_words = (cum->words + 1) & ~1;
7674 if (align_words >= GP_ARG_NUM_REG)
7680 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7682 return gen_rtx_PARALLEL (mode,
7684 gen_rtx_EXPR_LIST (VOIDmode,
7686 gen_rtx_EXPR_LIST (VOIDmode,
7687 gen_rtx_REG (mode, cum->vregno),
7691 return gen_rtx_REG (mode, cum->vregno);
7692 else if (TARGET_ALTIVEC_ABI
7693 && (ALTIVEC_VECTOR_MODE (mode)
7694 || VSX_VECTOR_MODE (mode)
7695 || (type && TREE_CODE (type) == VECTOR_TYPE
7696 && int_size_in_bytes (type) == 16)))
7698 if (named || abi == ABI_V4)
7702 /* Vector parameters to varargs functions under AIX or Darwin
7703 get passed in memory and possibly also in GPRs. */
7704 int align, align_words, n_words;
7705 enum machine_mode part_mode;
7707 /* Vector parameters must be 16-byte aligned. This places them at
7708 2 mod 4 in terms of words in 32-bit mode, since the parameter
7709 save area starts at offset 24 from the stack. In 64-bit mode,
7710 they just have to start on an even word, since the parameter
7711 save area is 16-byte aligned. */
7713 align = (2 - cum->words) & 3;
7715 align = cum->words & 1;
7716 align_words = cum->words + align;
7718 /* Out of registers? Memory, then. */
7719 if (align_words >= GP_ARG_NUM_REG)
7722 if (TARGET_32BIT && TARGET_POWERPC64)
7723 return rs6000_mixed_function_arg (mode, type, align_words);
7725 /* The vector value goes in GPRs. Only the part of the
7726 value in GPRs is reported here. */
7728 n_words = rs6000_arg_size (mode, type);
7729 if (align_words + n_words > GP_ARG_NUM_REG)
7730 /* Fortunately, there are only two possibilities, the value
7731 is either wholly in GPRs or half in GPRs and half not. */
7734 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7737 else if (TARGET_SPE_ABI && TARGET_SPE
7738 && (SPE_VECTOR_MODE (mode)
7739 || (TARGET_E500_DOUBLE && (mode == DFmode
7742 || mode == TCmode))))
7743 return rs6000_spe_function_arg (cum, mode, type);
7745 else if (abi == ABI_V4)
7747 if (TARGET_HARD_FLOAT && TARGET_FPRS
7748 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7749 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7750 || (mode == TFmode && !TARGET_IEEEQUAD)
7751 || mode == SDmode || mode == DDmode || mode == TDmode))
7753 /* _Decimal128 must use an even/odd register pair. This assumes
7754 that the register number is odd when fregno is odd. */
7755 if (mode == TDmode && (cum->fregno % 2) == 1)
7758 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7759 <= FP_ARG_V4_MAX_REG)
7760 return gen_rtx_REG (mode, cum->fregno);
7766 int n_words = rs6000_arg_size (mode, type);
7767 int gregno = cum->sysv_gregno;
7769 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7770 (r7,r8) or (r9,r10). As does any other 2 word item such
7771 as complex int due to a historical mistake. */
7773 gregno += (1 - gregno) & 1;
7775 /* Multi-reg args are not split between registers and stack. */
7776 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7779 if (TARGET_32BIT && TARGET_POWERPC64)
7780 return rs6000_mixed_function_arg (mode, type,
7781 gregno - GP_ARG_MIN_REG);
7782 return gen_rtx_REG (mode, gregno);
7787 int align_words = rs6000_parm_start (mode, type, cum->words);
7789 /* _Decimal128 must be passed in an even/odd float register pair.
7790 This assumes that the register number is odd when fregno is odd. */
7791 if (mode == TDmode && (cum->fregno % 2) == 1)
7794 if (USE_FP_FOR_ARG_P (cum, mode, type))
7796 rtx rvec[GP_ARG_NUM_REG + 1];
7800 enum machine_mode fmode = mode;
7801 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7803 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7805 /* Currently, we only ever need one reg here because complex
7806 doubles are split. */
7807 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7808 && (fmode == TFmode || fmode == TDmode));
7810 /* Long double or _Decimal128 split over regs and memory. */
7811 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7814 /* Do we also need to pass this arg in the parameter save
7817 && (cum->nargs_prototype <= 0
7818 || (DEFAULT_ABI == ABI_AIX
7820 && align_words >= GP_ARG_NUM_REG)));
7822 if (!needs_psave && mode == fmode)
7823 return gen_rtx_REG (fmode, cum->fregno);
7828 /* Describe the part that goes in gprs or the stack.
7829 This piece must come first, before the fprs. */
7830 if (align_words < GP_ARG_NUM_REG)
7832 unsigned long n_words = rs6000_arg_size (mode, type);
7834 if (align_words + n_words > GP_ARG_NUM_REG
7835 || (TARGET_32BIT && TARGET_POWERPC64))
7837 /* If this is partially on the stack, then we only
7838 include the portion actually in registers here. */
7839 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7842 if (align_words + n_words > GP_ARG_NUM_REG)
7843 /* Not all of the arg fits in gprs. Say that it
7844 goes in memory too, using a magic NULL_RTX
7845 component. Also see comment in
7846 rs6000_mixed_function_arg for why the normal
7847 function_arg_partial_nregs scheme doesn't work
7849 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7853 r = gen_rtx_REG (rmode,
7854 GP_ARG_MIN_REG + align_words);
7855 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7856 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7858 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7862 /* The whole arg fits in gprs. */
7863 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7864 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7868 /* It's entirely in memory. */
7869 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7872 /* Describe where this piece goes in the fprs. */
7873 r = gen_rtx_REG (fmode, cum->fregno);
7874 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7876 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7878 else if (align_words < GP_ARG_NUM_REG)
7880 if (TARGET_32BIT && TARGET_POWERPC64)
7881 return rs6000_mixed_function_arg (mode, type, align_words);
7883 if (mode == BLKmode)
7886 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7893 /* For an arg passed partly in registers and partly in memory, this is
7894 the number of bytes passed in registers. For args passed entirely in
7895 registers or entirely in memory, zero. When an arg is described by a
7896 PARALLEL, perhaps using more than one register type, this function
7897 returns the number of bytes used by the first element of the PARALLEL. */
7900 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7901 tree type, bool named)
7906 if (DEFAULT_ABI == ABI_V4)
7909 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7910 && cum->nargs_prototype >= 0)
7913 /* In this complicated case we just disable the partial_nregs code. */
7914 if (rs6000_darwin64_abi && mode == BLKmode
7915 && TREE_CODE (type) == RECORD_TYPE
7916 && int_size_in_bytes (type) > 0)
7919 align_words = rs6000_parm_start (mode, type, cum->words);
7921 if (USE_FP_FOR_ARG_P (cum, mode, type))
7923 /* If we are passing this arg in the fixed parameter save area
7924 (gprs or memory) as well as fprs, then this function should
7925 return the number of partial bytes passed in the parameter
7926 save area rather than partial bytes passed in fprs. */
7928 && (cum->nargs_prototype <= 0
7929 || (DEFAULT_ABI == ABI_AIX
7931 && align_words >= GP_ARG_NUM_REG)))
7933 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7934 > FP_ARG_MAX_REG + 1)
7935 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7936 else if (cum->nargs_prototype >= 0)
7940 if (align_words < GP_ARG_NUM_REG
7941 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7942 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7944 if (ret != 0 && TARGET_DEBUG_ARG)
7945 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7950 /* A C expression that indicates when an argument must be passed by
7951 reference. If nonzero for an argument, a copy of that argument is
7952 made in memory and a pointer to the argument is passed instead of
7953 the argument itself. The pointer is passed in whatever way is
7954 appropriate for passing a pointer to that type.
7956 Under V.4, aggregates and long double are passed by reference.
7958 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7959 reference unless the AltiVec vector extension ABI is in force.
7961 As an extension to all ABIs, variable sized types are passed by
7965 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7966 enum machine_mode mode, const_tree type,
7967 bool named ATTRIBUTE_UNUSED)
7969 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7971 if (TARGET_DEBUG_ARG)
7972 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7979 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7981 if (TARGET_DEBUG_ARG)
7982 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7986 if (int_size_in_bytes (type) < 0)
7988 if (TARGET_DEBUG_ARG)
7989 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7993 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7994 modes only exist for GCC vector types if -maltivec. */
7995 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7997 if (TARGET_DEBUG_ARG)
7998 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8002 /* Pass synthetic vectors in memory. */
8003 if (TREE_CODE (type) == VECTOR_TYPE
8004 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8006 static bool warned_for_pass_big_vectors = false;
8007 if (TARGET_DEBUG_ARG)
8008 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8009 if (!warned_for_pass_big_vectors)
8011 warning (0, "GCC vector passed by reference: "
8012 "non-standard ABI extension with no compatibility guarantee");
8013 warned_for_pass_big_vectors = true;
8022 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8025 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8030 for (i = 0; i < nregs; i++)
8032 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8033 if (reload_completed)
8035 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8038 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8039 i * GET_MODE_SIZE (reg_mode));
8042 tem = replace_equiv_address (tem, XEXP (tem, 0));
8046 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8050 /* Perform any needed actions needed for a function that is receiving a
8051 variable number of arguments.
8055 MODE and TYPE are the mode and type of the current parameter.
8057 PRETEND_SIZE is a variable that should be set to the amount of stack
8058 that must be pushed by the prolog to pretend that our caller pushed
8061 Normally, this macro will push all remaining incoming registers on the
8062 stack and set PRETEND_SIZE to the length of the registers pushed. */
8065 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8066 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8069 CUMULATIVE_ARGS next_cum;
8070 int reg_size = TARGET_32BIT ? 4 : 8;
8071 rtx save_area = NULL_RTX, mem;
8072 int first_reg_offset;
8075 /* Skip the last named argument. */
8077 function_arg_advance (&next_cum, mode, type, 1, 0);
8079 if (DEFAULT_ABI == ABI_V4)
8081 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8085 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8086 HOST_WIDE_INT offset = 0;
8088 /* Try to optimize the size of the varargs save area.
8089 The ABI requires that ap.reg_save_area is doubleword
8090 aligned, but we don't need to allocate space for all
8091 the bytes, only those to which we actually will save
8093 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8094 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8095 if (TARGET_HARD_FLOAT && TARGET_FPRS
8096 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8097 && cfun->va_list_fpr_size)
8100 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8101 * UNITS_PER_FP_WORD;
8102 if (cfun->va_list_fpr_size
8103 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8104 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8106 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8107 * UNITS_PER_FP_WORD;
8111 offset = -((first_reg_offset * reg_size) & ~7);
8112 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8114 gpr_reg_num = cfun->va_list_gpr_size;
8115 if (reg_size == 4 && (first_reg_offset & 1))
8118 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8121 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8123 - (int) (GP_ARG_NUM_REG * reg_size);
8125 if (gpr_size + fpr_size)
8128 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8129 gcc_assert (GET_CODE (reg_save_area) == MEM);
8130 reg_save_area = XEXP (reg_save_area, 0);
8131 if (GET_CODE (reg_save_area) == PLUS)
8133 gcc_assert (XEXP (reg_save_area, 0)
8134 == virtual_stack_vars_rtx);
8135 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8136 offset += INTVAL (XEXP (reg_save_area, 1));
8139 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8142 cfun->machine->varargs_save_offset = offset;
8143 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8148 first_reg_offset = next_cum.words;
8149 save_area = virtual_incoming_args_rtx;
8151 if (targetm.calls.must_pass_in_stack (mode, type))
8152 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8155 set = get_varargs_alias_set ();
8156 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8157 && cfun->va_list_gpr_size)
8159 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8161 if (va_list_gpr_counter_field)
8163 /* V4 va_list_gpr_size counts number of registers needed. */
8164 if (nregs > cfun->va_list_gpr_size)
8165 nregs = cfun->va_list_gpr_size;
8169 /* char * va_list instead counts number of bytes needed. */
8170 if (nregs > cfun->va_list_gpr_size / reg_size)
8171 nregs = cfun->va_list_gpr_size / reg_size;
8174 mem = gen_rtx_MEM (BLKmode,
8175 plus_constant (save_area,
8176 first_reg_offset * reg_size));
8177 MEM_NOTRAP_P (mem) = 1;
8178 set_mem_alias_set (mem, set);
8179 set_mem_align (mem, BITS_PER_WORD);
8181 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8185 /* Save FP registers if needed. */
8186 if (DEFAULT_ABI == ABI_V4
8187 && TARGET_HARD_FLOAT && TARGET_FPRS
8189 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8190 && cfun->va_list_fpr_size)
8192 int fregno = next_cum.fregno, nregs;
8193 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8194 rtx lab = gen_label_rtx ();
8195 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8196 * UNITS_PER_FP_WORD);
8199 (gen_rtx_SET (VOIDmode,
8201 gen_rtx_IF_THEN_ELSE (VOIDmode,
8202 gen_rtx_NE (VOIDmode, cr1,
8204 gen_rtx_LABEL_REF (VOIDmode, lab),
8208 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8209 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8211 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8213 plus_constant (save_area, off));
8214 MEM_NOTRAP_P (mem) = 1;
8215 set_mem_alias_set (mem, set);
8216 set_mem_align (mem, GET_MODE_ALIGNMENT (
8217 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8218 ? DFmode : SFmode));
8219 emit_move_insn (mem, gen_rtx_REG (
8220 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8221 ? DFmode : SFmode, fregno));
8228 /* Create the va_list data type. */
8231 rs6000_build_builtin_va_list (void)
8233 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8235 /* For AIX, prefer 'char *' because that's what the system
8236 header files like. */
8237 if (DEFAULT_ABI != ABI_V4)
8238 return build_pointer_type (char_type_node);
8240 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8241 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8242 get_identifier ("__va_list_tag"), record);
8244 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8245 unsigned_char_type_node);
8246 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8247 unsigned_char_type_node);
8248 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8250 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8251 get_identifier ("reserved"), short_unsigned_type_node);
8252 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8253 get_identifier ("overflow_arg_area"),
8255 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8256 get_identifier ("reg_save_area"),
8259 va_list_gpr_counter_field = f_gpr;
8260 va_list_fpr_counter_field = f_fpr;
8262 DECL_FIELD_CONTEXT (f_gpr) = record;
8263 DECL_FIELD_CONTEXT (f_fpr) = record;
8264 DECL_FIELD_CONTEXT (f_res) = record;
8265 DECL_FIELD_CONTEXT (f_ovf) = record;
8266 DECL_FIELD_CONTEXT (f_sav) = record;
8268 TREE_CHAIN (record) = type_decl;
8269 TYPE_NAME (record) = type_decl;
8270 TYPE_FIELDS (record) = f_gpr;
8271 TREE_CHAIN (f_gpr) = f_fpr;
8272 TREE_CHAIN (f_fpr) = f_res;
8273 TREE_CHAIN (f_res) = f_ovf;
8274 TREE_CHAIN (f_ovf) = f_sav;
8276 layout_type (record);
8278 /* The correct type is an array type of one element. */
8279 return build_array_type (record, build_index_type (size_zero_node));
8282 /* Implement va_start. */
8285 rs6000_va_start (tree valist, rtx nextarg)
8287 HOST_WIDE_INT words, n_gpr, n_fpr;
8288 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8289 tree gpr, fpr, ovf, sav, t;
8291 /* Only SVR4 needs something special. */
8292 if (DEFAULT_ABI != ABI_V4)
8294 std_expand_builtin_va_start (valist, nextarg);
8298 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8299 f_fpr = TREE_CHAIN (f_gpr);
8300 f_res = TREE_CHAIN (f_fpr);
8301 f_ovf = TREE_CHAIN (f_res);
8302 f_sav = TREE_CHAIN (f_ovf);
8304 valist = build_va_arg_indirect_ref (valist);
8305 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8306 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8308 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8310 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8313 /* Count number of gp and fp argument registers used. */
8314 words = crtl->args.info.words;
8315 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8317 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8320 if (TARGET_DEBUG_ARG)
8321 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8322 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8323 words, n_gpr, n_fpr);
8325 if (cfun->va_list_gpr_size)
8327 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8328 build_int_cst (NULL_TREE, n_gpr));
8329 TREE_SIDE_EFFECTS (t) = 1;
8330 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8333 if (cfun->va_list_fpr_size)
8335 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8336 build_int_cst (NULL_TREE, n_fpr));
8337 TREE_SIDE_EFFECTS (t) = 1;
8338 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8341 /* Find the overflow area. */
8342 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8344 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8345 size_int (words * UNITS_PER_WORD));
8346 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8347 TREE_SIDE_EFFECTS (t) = 1;
8348 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8350 /* If there were no va_arg invocations, don't set up the register
8352 if (!cfun->va_list_gpr_size
8353 && !cfun->va_list_fpr_size
8354 && n_gpr < GP_ARG_NUM_REG
8355 && n_fpr < FP_ARG_V4_MAX_REG)
8358 /* Find the register save area. */
8359 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8360 if (cfun->machine->varargs_save_offset)
8361 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8362 size_int (cfun->machine->varargs_save_offset));
8363 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8364 TREE_SIDE_EFFECTS (t) = 1;
8365 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8368 /* Implement va_arg. */
8371 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8374 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8375 tree gpr, fpr, ovf, sav, reg, t, u;
8376 int size, rsize, n_reg, sav_ofs, sav_scale;
8377 tree lab_false, lab_over, addr;
8379 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8383 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8385 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8386 return build_va_arg_indirect_ref (t);
8389 if (DEFAULT_ABI != ABI_V4)
8391 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8393 tree elem_type = TREE_TYPE (type);
8394 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8395 int elem_size = GET_MODE_SIZE (elem_mode);
8397 if (elem_size < UNITS_PER_WORD)
8399 tree real_part, imag_part;
8400 gimple_seq post = NULL;
8402 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8404 /* Copy the value into a temporary, lest the formal temporary
8405 be reused out from under us. */
8406 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8407 gimple_seq_add_seq (pre_p, post);
8409 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8412 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8416 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8419 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8420 f_fpr = TREE_CHAIN (f_gpr);
8421 f_res = TREE_CHAIN (f_fpr);
8422 f_ovf = TREE_CHAIN (f_res);
8423 f_sav = TREE_CHAIN (f_ovf);
8425 valist = build_va_arg_indirect_ref (valist);
8426 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8427 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8429 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8431 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8434 size = int_size_in_bytes (type);
8435 rsize = (size + 3) / 4;
8438 if (TARGET_HARD_FLOAT && TARGET_FPRS
8439 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8440 || (TARGET_DOUBLE_FLOAT
8441 && (TYPE_MODE (type) == DFmode
8442 || TYPE_MODE (type) == TFmode
8443 || TYPE_MODE (type) == SDmode
8444 || TYPE_MODE (type) == DDmode
8445 || TYPE_MODE (type) == TDmode))))
8447 /* FP args go in FP registers, if present. */
8449 n_reg = (size + 7) / 8;
8450 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8451 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8452 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8457 /* Otherwise into GP registers. */
8466 /* Pull the value out of the saved registers.... */
8469 addr = create_tmp_var (ptr_type_node, "addr");
8471 /* AltiVec vectors never go in registers when -mabi=altivec. */
8472 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8476 lab_false = create_artificial_label (input_location);
8477 lab_over = create_artificial_label (input_location);
8479 /* Long long and SPE vectors are aligned in the registers.
8480 As are any other 2 gpr item such as complex int due to a
8481 historical mistake. */
8483 if (n_reg == 2 && reg == gpr)
8486 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8487 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8488 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8489 unshare_expr (reg), u);
8491 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8492 reg number is 0 for f1, so we want to make it odd. */
8493 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8495 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8496 build_int_cst (TREE_TYPE (reg), 1));
8497 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8500 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8501 t = build2 (GE_EXPR, boolean_type_node, u, t);
8502 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8503 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8504 gimplify_and_add (t, pre_p);
8508 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8510 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8511 build_int_cst (TREE_TYPE (reg), n_reg));
8512 u = fold_convert (sizetype, u);
8513 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8514 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8516 /* _Decimal32 varargs are located in the second word of the 64-bit
8517 FP register for 32-bit binaries. */
8518 if (!TARGET_POWERPC64
8519 && TARGET_HARD_FLOAT && TARGET_FPRS
8520 && TYPE_MODE (type) == SDmode)
8521 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8523 gimplify_assign (addr, t, pre_p);
8525 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8527 stmt = gimple_build_label (lab_false);
8528 gimple_seq_add_stmt (pre_p, stmt);
8530 if ((n_reg == 2 && !regalign) || n_reg > 2)
8532 /* Ensure that we don't find any more args in regs.
8533 Alignment has taken care of for special cases. */
8534 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8538 /* ... otherwise out of the overflow area. */
8540 /* Care for on-stack alignment if needed. */
8544 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8545 t = fold_convert (sizetype, t);
8546 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8548 t = fold_convert (TREE_TYPE (ovf), t);
8550 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8552 gimplify_assign (unshare_expr (addr), t, pre_p);
8554 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8555 gimplify_assign (unshare_expr (ovf), t, pre_p);
8559 stmt = gimple_build_label (lab_over);
8560 gimple_seq_add_stmt (pre_p, stmt);
8563 if (STRICT_ALIGNMENT
8564 && (TYPE_ALIGN (type)
8565 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8567 /* The value (of type complex double, for example) may not be
8568 aligned in memory in the saved registers, so copy via a
8569 temporary. (This is the same code as used for SPARC.) */
8570 tree tmp = create_tmp_var (type, "va_arg_tmp");
8571 tree dest_addr = build_fold_addr_expr (tmp);
8573 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8574 3, dest_addr, addr, size_int (rsize * 4));
8576 gimplify_and_add (copy, pre_p);
8580 addr = fold_convert (ptrtype, addr);
8581 return build_va_arg_indirect_ref (addr);
8587 def_builtin (int mask, const char *name, tree type, int code)
8589 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8592 if (rs6000_builtin_decls[code])
8593 fatal_error ("internal error: builtin function to %s already processed.",
8596 rs6000_builtin_decls[code] = t =
8597 add_builtin_function (name, type, code, BUILT_IN_MD,
8600 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8601 switch (builtin_classify[code])
8606 /* assume builtin can do anything. */
8607 case RS6000_BTC_MISC:
8610 /* const function, function only depends on the inputs. */
8611 case RS6000_BTC_CONST:
8612 TREE_READONLY (t) = 1;
8613 TREE_NOTHROW (t) = 1;
8616 /* pure function, function can read global memory. */
8617 case RS6000_BTC_PURE:
8618 DECL_PURE_P (t) = 1;
8619 TREE_NOTHROW (t) = 1;
8622 /* Function is a math function. If rounding mode is on, then treat
8623 the function as not reading global memory, but it can have
8624 arbitrary side effects. If it is off, then assume the function is
8625 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8626 attribute in builtin-attribute.def that is used for the math
8628 case RS6000_BTC_FP_PURE:
8629 TREE_NOTHROW (t) = 1;
8630 if (flag_rounding_math)
8632 DECL_PURE_P (t) = 1;
8633 DECL_IS_NOVOPS (t) = 1;
8636 TREE_READONLY (t) = 1;
8642 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8644 static const struct builtin_description bdesc_3arg[] =
8646 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8647 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8648 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8649 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8650 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8667 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8668 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8669 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8670 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8671 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8672 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8673 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8674 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8675 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8676 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8677 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8678 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8682 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8683 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8684 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8692 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8693 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8698 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8699 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8700 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8701 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8703 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8704 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8705 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8706 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8709 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8711 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8712 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8713 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8714 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8715 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8716 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8717 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8718 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8719 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8720 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8722 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8723 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8724 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8725 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8726 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8727 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8728 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8729 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8730 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8731 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8733 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8734 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8735 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8736 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8737 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8738 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8739 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8740 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8741 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8743 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8744 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8745 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8746 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8747 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8748 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8749 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8751 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8752 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8753 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8754 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8755 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8756 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8757 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8758 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8759 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8762 /* DST operations: void foo (void *, const int, const char). */
8764 static const struct builtin_description bdesc_dst[] =
8766 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8767 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8768 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8769 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8777 /* Simple binary operations: VECc = foo (VECa, VECb). */
8779 static struct builtin_description bdesc_2arg[] =
8781 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8782 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8783 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8784 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8785 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8786 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8787 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8788 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8789 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8790 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8791 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8792 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8793 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8794 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8795 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8796 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8797 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8798 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8799 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8800 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8803 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8804 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8805 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8806 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8807 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8808 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8809 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8810 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8811 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8812 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8813 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8814 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8815 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8816 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8817 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8818 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8819 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8820 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8821 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8822 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8823 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8824 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8825 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8826 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8827 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8828 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8829 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8830 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8831 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8832 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8833 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8834 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8835 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8836 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8837 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8838 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8839 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8840 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8841 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8846 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8847 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8848 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8849 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8850 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8851 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8852 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8860 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8861 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8862 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8863 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8864 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8865 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8866 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8867 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8871 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8872 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8873 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8874 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8875 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8876 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8877 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8878 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8879 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8880 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8881 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8882 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8883 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8884 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8885 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8886 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8887 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8888 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8889 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8890 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8891 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8892 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8895 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8896 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8898 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8899 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8900 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8901 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8902 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8903 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8904 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8905 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8906 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8907 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8908 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8910 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8911 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8912 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8913 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8914 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8915 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8916 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8917 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8918 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8919 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8920 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8922 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8923 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8924 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8925 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8926 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8927 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8929 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8930 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8931 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8932 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8933 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8934 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8935 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8936 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8937 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8938 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8939 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8940 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8942 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8943 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8955 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8956 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8982 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8983 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8998 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8999 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9016 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9017 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9050 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9051 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9069 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9071 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9072 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9074 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9075 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9076 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9077 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9078 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9079 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9080 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9081 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9082 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9083 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9085 /* Place holder, leave as first spe builtin. */
9086 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9087 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9088 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9089 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9090 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9091 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9092 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9093 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9094 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9095 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9096 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9097 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9098 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9099 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9100 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9101 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9102 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9103 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9104 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9105 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9106 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9107 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9108 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9109 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9110 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9111 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9112 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9113 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9114 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9115 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9116 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9117 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9118 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9119 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9120 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9121 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9122 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9123 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9124 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9125 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9126 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9127 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9128 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9129 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9130 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9131 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9132 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9133 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9134 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9135 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9136 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9137 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9138 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9139 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9140 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9141 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9142 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9143 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9144 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9145 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9146 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9147 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9148 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9149 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9150 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9151 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9152 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9153 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9154 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9155 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9156 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9157 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9158 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9159 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9160 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9161 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9162 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9163 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9164 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9165 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9166 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9167 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9168 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9169 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9170 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9171 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9172 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9173 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9174 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9175 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9176 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9177 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9178 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9179 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9180 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9181 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9182 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9183 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9184 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9185 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9186 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9187 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9188 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9189 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9190 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9191 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9192 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9193 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9194 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9196 /* SPE binary operations expecting a 5-bit unsigned literal. */
9197 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9199 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9200 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9201 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9202 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9203 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9204 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9205 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9206 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9207 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9208 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9209 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9210 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9211 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9212 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9213 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9214 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9215 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9216 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9217 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9218 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9219 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9220 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9221 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9222 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9223 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9224 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9226 /* Place-holder. Leave as last binary SPE builtin. */
9227 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9230 /* AltiVec predicates. */
9232 struct builtin_description_predicates
9234 const unsigned int mask;
9235 const enum insn_code icode;
9236 const char *const name;
9237 const enum rs6000_builtins code;
9240 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9242 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9243 ALTIVEC_BUILTIN_VCMPBFP_P },
9244 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9245 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9246 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9247 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9248 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9249 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9250 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9251 ALTIVEC_BUILTIN_VCMPEQUW_P },
9252 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9253 ALTIVEC_BUILTIN_VCMPGTSW_P },
9254 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9255 ALTIVEC_BUILTIN_VCMPGTUW_P },
9256 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9257 ALTIVEC_BUILTIN_VCMPEQUH_P },
9258 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9259 ALTIVEC_BUILTIN_VCMPGTSH_P },
9260 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9261 ALTIVEC_BUILTIN_VCMPGTUH_P },
9262 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9263 ALTIVEC_BUILTIN_VCMPEQUB_P },
9264 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9265 ALTIVEC_BUILTIN_VCMPGTSB_P },
9266 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9267 ALTIVEC_BUILTIN_VCMPGTUB_P },
9269 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9270 VSX_BUILTIN_XVCMPEQSP_P },
9271 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9272 VSX_BUILTIN_XVCMPGESP_P },
9273 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9274 VSX_BUILTIN_XVCMPGTSP_P },
9275 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9276 VSX_BUILTIN_XVCMPEQDP_P },
9277 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9278 VSX_BUILTIN_XVCMPGEDP_P },
9279 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9280 VSX_BUILTIN_XVCMPGTDP_P },
9282 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9283 ALTIVEC_BUILTIN_VCMPEQ_P },
9284 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9285 ALTIVEC_BUILTIN_VCMPGT_P },
9286 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9287 ALTIVEC_BUILTIN_VCMPGE_P }
9290 /* SPE predicates. */
9291 static struct builtin_description bdesc_spe_predicates[] =
9293 /* Place-holder. Leave as first. */
9294 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9295 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9296 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9297 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9298 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9299 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9300 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9301 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9302 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9303 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9304 /* Place-holder. Leave as last. */
9305 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9308 /* SPE evsel predicates. */
9309 static struct builtin_description bdesc_spe_evsel[] =
9311 /* Place-holder. Leave as first. */
9312 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9313 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9314 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9315 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9316 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9317 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9318 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9319 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9320 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9321 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9322 /* Place-holder. Leave as last. */
9323 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9326 /* PAIRED predicates. */
9327 static const struct builtin_description bdesc_paired_preds[] =
9329 /* Place-holder. Leave as first. */
9330 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9331 /* Place-holder. Leave as last. */
9332 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9335 /* ABS* operations. */
9337 static const struct builtin_description bdesc_abs[] =
9339 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9340 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9341 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9342 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9343 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9344 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9345 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9346 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9347 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9348 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9349 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9352 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9355 static struct builtin_description bdesc_1arg[] =
9357 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9358 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9359 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9360 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9361 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9362 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9363 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9364 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9365 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9366 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9367 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9368 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9369 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9370 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9371 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9372 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9375 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9376 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9377 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9378 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9379 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9380 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9382 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9383 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9384 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9385 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9386 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9387 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9389 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9390 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9391 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9392 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9393 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9394 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9396 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9397 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9398 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9399 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9400 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9401 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9403 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9404 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9405 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9406 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9408 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9409 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9410 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9411 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9412 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9413 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9414 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9415 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9416 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9418 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9419 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9420 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9421 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9422 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9423 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9424 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9425 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9426 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9428 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9429 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9430 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9431 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9432 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9454 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9455 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9456 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9458 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9459 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9460 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9461 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9463 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9464 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9465 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9466 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9467 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9468 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9469 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9470 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9471 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9472 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9473 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9474 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9475 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9476 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9477 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9478 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9479 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9480 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9481 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9482 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9483 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9484 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9485 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9486 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9487 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9488 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9489 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9490 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9491 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9492 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9494 /* Place-holder. Leave as last unary SPE builtin. */
9495 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9497 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9498 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9499 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9500 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9501 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9505 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9508 tree arg0 = CALL_EXPR_ARG (exp, 0);
9509 rtx op0 = expand_normal (arg0);
9510 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9511 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9513 if (icode == CODE_FOR_nothing)
9514 /* Builtin not supported on this processor. */
9517 /* If we got invalid arguments bail out before generating bad rtl. */
9518 if (arg0 == error_mark_node)
9521 if (icode == CODE_FOR_altivec_vspltisb
9522 || icode == CODE_FOR_altivec_vspltish
9523 || icode == CODE_FOR_altivec_vspltisw
9524 || icode == CODE_FOR_spe_evsplatfi
9525 || icode == CODE_FOR_spe_evsplati)
9527 /* Only allow 5-bit *signed* literals. */
9528 if (GET_CODE (op0) != CONST_INT
9529 || INTVAL (op0) > 15
9530 || INTVAL (op0) < -16)
9532 error ("argument 1 must be a 5-bit signed literal");
9538 || GET_MODE (target) != tmode
9539 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9540 target = gen_reg_rtx (tmode);
9542 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9543 op0 = copy_to_mode_reg (mode0, op0);
9545 pat = GEN_FCN (icode) (target, op0);
9554 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9556 rtx pat, scratch1, scratch2;
9557 tree arg0 = CALL_EXPR_ARG (exp, 0);
9558 rtx op0 = expand_normal (arg0);
9559 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9560 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9562 /* If we have invalid arguments, bail out before generating bad rtl. */
9563 if (arg0 == error_mark_node)
9567 || GET_MODE (target) != tmode
9568 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9569 target = gen_reg_rtx (tmode);
9571 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9572 op0 = copy_to_mode_reg (mode0, op0);
9574 scratch1 = gen_reg_rtx (mode0);
9575 scratch2 = gen_reg_rtx (mode0);
9577 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9586 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9589 tree arg0 = CALL_EXPR_ARG (exp, 0);
9590 tree arg1 = CALL_EXPR_ARG (exp, 1);
9591 rtx op0 = expand_normal (arg0);
9592 rtx op1 = expand_normal (arg1);
9593 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9594 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9595 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9597 if (icode == CODE_FOR_nothing)
9598 /* Builtin not supported on this processor. */
9601 /* If we got invalid arguments bail out before generating bad rtl. */
9602 if (arg0 == error_mark_node || arg1 == error_mark_node)
9605 if (icode == CODE_FOR_altivec_vcfux
9606 || icode == CODE_FOR_altivec_vcfsx
9607 || icode == CODE_FOR_altivec_vctsxs
9608 || icode == CODE_FOR_altivec_vctuxs
9609 || icode == CODE_FOR_altivec_vspltb
9610 || icode == CODE_FOR_altivec_vsplth
9611 || icode == CODE_FOR_altivec_vspltw
9612 || icode == CODE_FOR_spe_evaddiw
9613 || icode == CODE_FOR_spe_evldd
9614 || icode == CODE_FOR_spe_evldh
9615 || icode == CODE_FOR_spe_evldw
9616 || icode == CODE_FOR_spe_evlhhesplat
9617 || icode == CODE_FOR_spe_evlhhossplat
9618 || icode == CODE_FOR_spe_evlhhousplat
9619 || icode == CODE_FOR_spe_evlwhe
9620 || icode == CODE_FOR_spe_evlwhos
9621 || icode == CODE_FOR_spe_evlwhou
9622 || icode == CODE_FOR_spe_evlwhsplat
9623 || icode == CODE_FOR_spe_evlwwsplat
9624 || icode == CODE_FOR_spe_evrlwi
9625 || icode == CODE_FOR_spe_evslwi
9626 || icode == CODE_FOR_spe_evsrwis
9627 || icode == CODE_FOR_spe_evsubifw
9628 || icode == CODE_FOR_spe_evsrwiu)
9630 /* Only allow 5-bit unsigned literals. */
9632 if (TREE_CODE (arg1) != INTEGER_CST
9633 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9635 error ("argument 2 must be a 5-bit unsigned literal");
9641 || GET_MODE (target) != tmode
9642 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9643 target = gen_reg_rtx (tmode);
9645 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9646 op0 = copy_to_mode_reg (mode0, op0);
9647 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9648 op1 = copy_to_mode_reg (mode1, op1);
9650 pat = GEN_FCN (icode) (target, op0, op1);
9659 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9662 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9663 tree arg0 = CALL_EXPR_ARG (exp, 1);
9664 tree arg1 = CALL_EXPR_ARG (exp, 2);
9665 rtx op0 = expand_normal (arg0);
9666 rtx op1 = expand_normal (arg1);
9667 enum machine_mode tmode = SImode;
9668 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9669 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9672 if (TREE_CODE (cr6_form) != INTEGER_CST)
9674 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9678 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9680 gcc_assert (mode0 == mode1);
9682 /* If we have invalid arguments, bail out before generating bad rtl. */
9683 if (arg0 == error_mark_node || arg1 == error_mark_node)
9687 || GET_MODE (target) != tmode
9688 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9689 target = gen_reg_rtx (tmode);
9691 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9692 op0 = copy_to_mode_reg (mode0, op0);
9693 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9694 op1 = copy_to_mode_reg (mode1, op1);
9696 scratch = gen_reg_rtx (mode0);
9698 pat = GEN_FCN (icode) (scratch, op0, op1);
9703 /* The vec_any* and vec_all* predicates use the same opcodes for two
9704 different operations, but the bits in CR6 will be different
9705 depending on what information we want. So we have to play tricks
9706 with CR6 to get the right bits out.
9708 If you think this is disgusting, look at the specs for the
9709 AltiVec predicates. */
9711 switch (cr6_form_int)
9714 emit_insn (gen_cr6_test_for_zero (target));
9717 emit_insn (gen_cr6_test_for_zero_reverse (target));
9720 emit_insn (gen_cr6_test_for_lt (target));
9723 emit_insn (gen_cr6_test_for_lt_reverse (target));
9726 error ("argument 1 of __builtin_altivec_predicate is out of range");
9734 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9737 tree arg0 = CALL_EXPR_ARG (exp, 0);
9738 tree arg1 = CALL_EXPR_ARG (exp, 1);
9739 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9740 enum machine_mode mode0 = Pmode;
9741 enum machine_mode mode1 = Pmode;
9742 rtx op0 = expand_normal (arg0);
9743 rtx op1 = expand_normal (arg1);
9745 if (icode == CODE_FOR_nothing)
9746 /* Builtin not supported on this processor. */
9749 /* If we got invalid arguments bail out before generating bad rtl. */
9750 if (arg0 == error_mark_node || arg1 == error_mark_node)
9754 || GET_MODE (target) != tmode
9755 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9756 target = gen_reg_rtx (tmode);
9758 op1 = copy_to_mode_reg (mode1, op1);
9760 if (op0 == const0_rtx)
9762 addr = gen_rtx_MEM (tmode, op1);
9766 op0 = copy_to_mode_reg (mode0, op0);
9767 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9770 pat = GEN_FCN (icode) (target, addr);
9780 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9783 tree arg0 = CALL_EXPR_ARG (exp, 0);
9784 tree arg1 = CALL_EXPR_ARG (exp, 1);
9785 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9786 enum machine_mode mode0 = Pmode;
9787 enum machine_mode mode1 = Pmode;
9788 rtx op0 = expand_normal (arg0);
9789 rtx op1 = expand_normal (arg1);
9791 if (icode == CODE_FOR_nothing)
9792 /* Builtin not supported on this processor. */
9795 /* If we got invalid arguments bail out before generating bad rtl. */
9796 if (arg0 == error_mark_node || arg1 == error_mark_node)
9800 || GET_MODE (target) != tmode
9801 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9802 target = gen_reg_rtx (tmode);
9804 op1 = copy_to_mode_reg (mode1, op1);
9806 if (op0 == const0_rtx)
9808 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9812 op0 = copy_to_mode_reg (mode0, op0);
9813 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9816 pat = GEN_FCN (icode) (target, addr);
9826 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9828 tree arg0 = CALL_EXPR_ARG (exp, 0);
9829 tree arg1 = CALL_EXPR_ARG (exp, 1);
9830 tree arg2 = CALL_EXPR_ARG (exp, 2);
9831 rtx op0 = expand_normal (arg0);
9832 rtx op1 = expand_normal (arg1);
9833 rtx op2 = expand_normal (arg2);
9835 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9836 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9837 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9839 /* Invalid arguments. Bail before doing anything stoopid! */
9840 if (arg0 == error_mark_node
9841 || arg1 == error_mark_node
9842 || arg2 == error_mark_node)
9845 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9846 op0 = copy_to_mode_reg (mode2, op0);
9847 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9848 op1 = copy_to_mode_reg (mode0, op1);
9849 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9850 op2 = copy_to_mode_reg (mode1, op2);
9852 pat = GEN_FCN (icode) (op1, op2, op0);
9859 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9861 tree arg0 = CALL_EXPR_ARG (exp, 0);
9862 tree arg1 = CALL_EXPR_ARG (exp, 1);
9863 tree arg2 = CALL_EXPR_ARG (exp, 2);
9864 rtx op0 = expand_normal (arg0);
9865 rtx op1 = expand_normal (arg1);
9866 rtx op2 = expand_normal (arg2);
9868 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9869 enum machine_mode mode1 = Pmode;
9870 enum machine_mode mode2 = Pmode;
9872 /* Invalid arguments. Bail before doing anything stoopid! */
9873 if (arg0 == error_mark_node
9874 || arg1 == error_mark_node
9875 || arg2 == error_mark_node)
9878 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9879 op0 = copy_to_mode_reg (tmode, op0);
9881 op2 = copy_to_mode_reg (mode2, op2);
9883 if (op1 == const0_rtx)
9885 addr = gen_rtx_MEM (tmode, op2);
9889 op1 = copy_to_mode_reg (mode1, op1);
9890 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9893 pat = GEN_FCN (icode) (addr, op0);
9900 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9902 tree arg0 = CALL_EXPR_ARG (exp, 0);
9903 tree arg1 = CALL_EXPR_ARG (exp, 1);
9904 tree arg2 = CALL_EXPR_ARG (exp, 2);
9905 rtx op0 = expand_normal (arg0);
9906 rtx op1 = expand_normal (arg1);
9907 rtx op2 = expand_normal (arg2);
9909 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9910 enum machine_mode mode1 = Pmode;
9911 enum machine_mode mode2 = Pmode;
9913 /* Invalid arguments. Bail before doing anything stoopid! */
9914 if (arg0 == error_mark_node
9915 || arg1 == error_mark_node
9916 || arg2 == error_mark_node)
9919 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9920 op0 = copy_to_mode_reg (tmode, op0);
9922 op2 = copy_to_mode_reg (mode2, op2);
9924 if (op1 == const0_rtx)
9926 addr = gen_rtx_MEM (tmode, op2);
9930 op1 = copy_to_mode_reg (mode1, op1);
9931 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9934 pat = GEN_FCN (icode) (addr, op0);
9941 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9944 tree arg0 = CALL_EXPR_ARG (exp, 0);
9945 tree arg1 = CALL_EXPR_ARG (exp, 1);
9946 tree arg2 = CALL_EXPR_ARG (exp, 2);
9947 rtx op0 = expand_normal (arg0);
9948 rtx op1 = expand_normal (arg1);
9949 rtx op2 = expand_normal (arg2);
9950 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9951 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9952 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9953 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9955 if (icode == CODE_FOR_nothing)
9956 /* Builtin not supported on this processor. */
9959 /* If we got invalid arguments bail out before generating bad rtl. */
9960 if (arg0 == error_mark_node
9961 || arg1 == error_mark_node
9962 || arg2 == error_mark_node)
9967 case CODE_FOR_altivec_vsldoi_v4sf:
9968 case CODE_FOR_altivec_vsldoi_v4si:
9969 case CODE_FOR_altivec_vsldoi_v8hi:
9970 case CODE_FOR_altivec_vsldoi_v16qi:
9971 /* Only allow 4-bit unsigned literals. */
9973 if (TREE_CODE (arg2) != INTEGER_CST
9974 || TREE_INT_CST_LOW (arg2) & ~0xf)
9976 error ("argument 3 must be a 4-bit unsigned literal");
9981 case CODE_FOR_vsx_xxpermdi_v2df:
9982 case CODE_FOR_vsx_xxpermdi_v2di:
9983 case CODE_FOR_vsx_xxsldwi_v16qi:
9984 case CODE_FOR_vsx_xxsldwi_v8hi:
9985 case CODE_FOR_vsx_xxsldwi_v4si:
9986 case CODE_FOR_vsx_xxsldwi_v4sf:
9987 case CODE_FOR_vsx_xxsldwi_v2di:
9988 case CODE_FOR_vsx_xxsldwi_v2df:
9989 /* Only allow 2-bit unsigned literals. */
9991 if (TREE_CODE (arg2) != INTEGER_CST
9992 || TREE_INT_CST_LOW (arg2) & ~0x3)
9994 error ("argument 3 must be a 2-bit unsigned literal");
9999 case CODE_FOR_vsx_set_v2df:
10000 case CODE_FOR_vsx_set_v2di:
10001 /* Only allow 1-bit unsigned literals. */
10003 if (TREE_CODE (arg2) != INTEGER_CST
10004 || TREE_INT_CST_LOW (arg2) & ~0x1)
10006 error ("argument 3 must be a 1-bit unsigned literal");
10016 || GET_MODE (target) != tmode
10017 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10018 target = gen_reg_rtx (tmode);
10020 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10021 op0 = copy_to_mode_reg (mode0, op0);
10022 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10023 op1 = copy_to_mode_reg (mode1, op1);
10024 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10025 op2 = copy_to_mode_reg (mode2, op2);
10027 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10028 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10030 pat = GEN_FCN (icode) (target, op0, op1, op2);
10038 /* Expand the lvx builtins. */
10040 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10042 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10043 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10045 enum machine_mode tmode, mode0;
10047 enum insn_code icode;
10051 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10052 icode = CODE_FOR_vector_load_v16qi;
10054 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10055 icode = CODE_FOR_vector_load_v8hi;
10057 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10058 icode = CODE_FOR_vector_load_v4si;
10060 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10061 icode = CODE_FOR_vector_load_v4sf;
10064 *expandedp = false;
10070 arg0 = CALL_EXPR_ARG (exp, 0);
10071 op0 = expand_normal (arg0);
10072 tmode = insn_data[icode].operand[0].mode;
10073 mode0 = insn_data[icode].operand[1].mode;
10076 || GET_MODE (target) != tmode
10077 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10078 target = gen_reg_rtx (tmode);
10080 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10081 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10083 pat = GEN_FCN (icode) (target, op0);
10090 /* Expand the stvx builtins. */
10092 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10095 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10096 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10098 enum machine_mode mode0, mode1;
10100 enum insn_code icode;
10104 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10105 icode = CODE_FOR_vector_store_v16qi;
10107 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10108 icode = CODE_FOR_vector_store_v8hi;
10110 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10111 icode = CODE_FOR_vector_store_v4si;
10113 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10114 icode = CODE_FOR_vector_store_v4sf;
10117 *expandedp = false;
10121 arg0 = CALL_EXPR_ARG (exp, 0);
10122 arg1 = CALL_EXPR_ARG (exp, 1);
10123 op0 = expand_normal (arg0);
10124 op1 = expand_normal (arg1);
10125 mode0 = insn_data[icode].operand[0].mode;
10126 mode1 = insn_data[icode].operand[1].mode;
10128 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10129 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10130 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10131 op1 = copy_to_mode_reg (mode1, op1);
10133 pat = GEN_FCN (icode) (op0, op1);
10141 /* Expand the dst builtins. */
10143 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10146 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10147 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10148 tree arg0, arg1, arg2;
10149 enum machine_mode mode0, mode1, mode2;
10150 rtx pat, op0, op1, op2;
10151 const struct builtin_description *d;
10154 *expandedp = false;
10156 /* Handle DST variants. */
10158 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10159 if (d->code == fcode)
10161 arg0 = CALL_EXPR_ARG (exp, 0);
10162 arg1 = CALL_EXPR_ARG (exp, 1);
10163 arg2 = CALL_EXPR_ARG (exp, 2);
10164 op0 = expand_normal (arg0);
10165 op1 = expand_normal (arg1);
10166 op2 = expand_normal (arg2);
10167 mode0 = insn_data[d->icode].operand[0].mode;
10168 mode1 = insn_data[d->icode].operand[1].mode;
10169 mode2 = insn_data[d->icode].operand[2].mode;
10171 /* Invalid arguments, bail out before generating bad rtl. */
10172 if (arg0 == error_mark_node
10173 || arg1 == error_mark_node
10174 || arg2 == error_mark_node)
10179 if (TREE_CODE (arg2) != INTEGER_CST
10180 || TREE_INT_CST_LOW (arg2) & ~0x3)
10182 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10186 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10187 op0 = copy_to_mode_reg (Pmode, op0);
10188 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10189 op1 = copy_to_mode_reg (mode1, op1);
10191 pat = GEN_FCN (d->icode) (op0, op1, op2);
10201 /* Expand vec_init builtin. */
10203 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10205 enum machine_mode tmode = TYPE_MODE (type);
10206 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10207 int i, n_elt = GET_MODE_NUNITS (tmode);
10208 rtvec v = rtvec_alloc (n_elt);
10210 gcc_assert (VECTOR_MODE_P (tmode));
10211 gcc_assert (n_elt == call_expr_nargs (exp));
10213 for (i = 0; i < n_elt; ++i)
10215 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10216 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10219 if (!target || !register_operand (target, tmode))
10220 target = gen_reg_rtx (tmode);
10222 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10226 /* Return the integer constant in ARG. Constrain it to be in the range
10227 of the subparts of VEC_TYPE; issue an error if not. */
10230 get_element_number (tree vec_type, tree arg)
10232 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10234 if (!host_integerp (arg, 1)
10235 || (elt = tree_low_cst (arg, 1), elt > max))
10237 error ("selector must be an integer constant in the range 0..%wi", max);
10244 /* Expand vec_set builtin. */
10246 altivec_expand_vec_set_builtin (tree exp)
10248 enum machine_mode tmode, mode1;
10249 tree arg0, arg1, arg2;
10253 arg0 = CALL_EXPR_ARG (exp, 0);
10254 arg1 = CALL_EXPR_ARG (exp, 1);
10255 arg2 = CALL_EXPR_ARG (exp, 2);
10257 tmode = TYPE_MODE (TREE_TYPE (arg0));
10258 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10259 gcc_assert (VECTOR_MODE_P (tmode));
10261 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10262 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10263 elt = get_element_number (TREE_TYPE (arg0), arg2);
10265 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10266 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10268 op0 = force_reg (tmode, op0);
10269 op1 = force_reg (mode1, op1);
10271 rs6000_expand_vector_set (op0, op1, elt);
10276 /* Expand vec_ext builtin. */
10278 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10280 enum machine_mode tmode, mode0;
10285 arg0 = CALL_EXPR_ARG (exp, 0);
10286 arg1 = CALL_EXPR_ARG (exp, 1);
10288 op0 = expand_normal (arg0);
10289 elt = get_element_number (TREE_TYPE (arg0), arg1);
10291 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10292 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10293 gcc_assert (VECTOR_MODE_P (mode0));
10295 op0 = force_reg (mode0, op0);
10297 if (optimize || !target || !register_operand (target, tmode))
10298 target = gen_reg_rtx (tmode);
10300 rs6000_expand_vector_extract (target, op0, elt);
10305 /* Expand the builtin in EXP and store the result in TARGET. Store
10306 true in *EXPANDEDP if we found a builtin to expand. */
10308 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10310 const struct builtin_description *d;
10311 const struct builtin_description_predicates *dp;
10313 enum insn_code icode;
10314 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10317 enum machine_mode tmode, mode0;
10318 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10320 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10321 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10322 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10323 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10326 error ("unresolved overload for Altivec builtin %qF", fndecl);
10330 target = altivec_expand_ld_builtin (exp, target, expandedp);
10334 target = altivec_expand_st_builtin (exp, target, expandedp);
10338 target = altivec_expand_dst_builtin (exp, target, expandedp);
10346 case ALTIVEC_BUILTIN_STVX:
10347 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10348 case ALTIVEC_BUILTIN_STVEBX:
10349 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10350 case ALTIVEC_BUILTIN_STVEHX:
10351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10352 case ALTIVEC_BUILTIN_STVEWX:
10353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10354 case ALTIVEC_BUILTIN_STVXL:
10355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10357 case ALTIVEC_BUILTIN_STVLX:
10358 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10359 case ALTIVEC_BUILTIN_STVLXL:
10360 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10361 case ALTIVEC_BUILTIN_STVRX:
10362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10363 case ALTIVEC_BUILTIN_STVRXL:
10364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10366 case ALTIVEC_BUILTIN_MFVSCR:
10367 icode = CODE_FOR_altivec_mfvscr;
10368 tmode = insn_data[icode].operand[0].mode;
10371 || GET_MODE (target) != tmode
10372 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10373 target = gen_reg_rtx (tmode);
10375 pat = GEN_FCN (icode) (target);
10381 case ALTIVEC_BUILTIN_MTVSCR:
10382 icode = CODE_FOR_altivec_mtvscr;
10383 arg0 = CALL_EXPR_ARG (exp, 0);
10384 op0 = expand_normal (arg0);
10385 mode0 = insn_data[icode].operand[0].mode;
10387 /* If we got invalid arguments bail out before generating bad rtl. */
10388 if (arg0 == error_mark_node)
10391 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10392 op0 = copy_to_mode_reg (mode0, op0);
10394 pat = GEN_FCN (icode) (op0);
10399 case ALTIVEC_BUILTIN_DSSALL:
10400 emit_insn (gen_altivec_dssall ());
10403 case ALTIVEC_BUILTIN_DSS:
10404 icode = CODE_FOR_altivec_dss;
10405 arg0 = CALL_EXPR_ARG (exp, 0);
10407 op0 = expand_normal (arg0);
10408 mode0 = insn_data[icode].operand[0].mode;
10410 /* If we got invalid arguments bail out before generating bad rtl. */
10411 if (arg0 == error_mark_node)
10414 if (TREE_CODE (arg0) != INTEGER_CST
10415 || TREE_INT_CST_LOW (arg0) & ~0x3)
10417 error ("argument to dss must be a 2-bit unsigned literal");
10421 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10422 op0 = copy_to_mode_reg (mode0, op0);
10424 emit_insn (gen_altivec_dss (op0));
10427 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10428 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10429 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10430 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10431 case VSX_BUILTIN_VEC_INIT_V2DF:
10432 case VSX_BUILTIN_VEC_INIT_V2DI:
10433 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10435 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10436 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10437 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10438 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10439 case VSX_BUILTIN_VEC_SET_V2DF:
10440 case VSX_BUILTIN_VEC_SET_V2DI:
10441 return altivec_expand_vec_set_builtin (exp);
10443 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10444 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10445 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10446 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10447 case VSX_BUILTIN_VEC_EXT_V2DF:
10448 case VSX_BUILTIN_VEC_EXT_V2DI:
10449 return altivec_expand_vec_ext_builtin (exp, target);
10453 /* Fall through. */
10456 /* Expand abs* operations. */
10458 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10459 if (d->code == fcode)
10460 return altivec_expand_abs_builtin (d->icode, exp, target);
10462 /* Expand the AltiVec predicates. */
10463 dp = bdesc_altivec_preds;
10464 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10465 if (dp->code == fcode)
10466 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10468 /* LV* are funky. We initialized them differently. */
10471 case ALTIVEC_BUILTIN_LVSL:
10472 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10473 exp, target, false);
10474 case ALTIVEC_BUILTIN_LVSR:
10475 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10476 exp, target, false);
10477 case ALTIVEC_BUILTIN_LVEBX:
10478 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10479 exp, target, false);
10480 case ALTIVEC_BUILTIN_LVEHX:
10481 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10482 exp, target, false);
10483 case ALTIVEC_BUILTIN_LVEWX:
10484 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10485 exp, target, false);
10486 case ALTIVEC_BUILTIN_LVXL:
10487 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10488 exp, target, false);
10489 case ALTIVEC_BUILTIN_LVX:
10490 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10491 exp, target, false);
10492 case ALTIVEC_BUILTIN_LVLX:
10493 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10494 exp, target, true);
10495 case ALTIVEC_BUILTIN_LVLXL:
10496 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10497 exp, target, true);
10498 case ALTIVEC_BUILTIN_LVRX:
10499 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10500 exp, target, true);
10501 case ALTIVEC_BUILTIN_LVRXL:
10502 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10503 exp, target, true);
10506 /* Fall through. */
10509 *expandedp = false;
10513 /* Expand the builtin in EXP and store the result in TARGET. Store
10514 true in *EXPANDEDP if we found a builtin to expand. */
10516 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10518 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10519 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10520 const struct builtin_description *d;
10527 case PAIRED_BUILTIN_STX:
10528 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10529 case PAIRED_BUILTIN_LX:
10530 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10533 /* Fall through. */
10536 /* Expand the paired predicates. */
10537 d = bdesc_paired_preds;
10538 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10539 if (d->code == fcode)
10540 return paired_expand_predicate_builtin (d->icode, exp, target);
10542 *expandedp = false;
10546 /* Binops that need to be initialized manually, but can be expanded
10547 automagically by rs6000_expand_binop_builtin. */
10548 static struct builtin_description bdesc_2arg_spe[] =
10550 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10551 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10552 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10553 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10554 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10555 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10556 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10557 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10558 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10559 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10560 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10561 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10562 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10563 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10564 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10565 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10566 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10567 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10568 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10569 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10570 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10571 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10574 /* Expand the builtin in EXP and store the result in TARGET. Store
10575 true in *EXPANDEDP if we found a builtin to expand.
10577 This expands the SPE builtins that are not simple unary and binary
10580 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10582 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10584 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10585 enum insn_code icode;
10586 enum machine_mode tmode, mode0;
10588 struct builtin_description *d;
10593 /* Syntax check for a 5-bit unsigned immediate. */
10596 case SPE_BUILTIN_EVSTDD:
10597 case SPE_BUILTIN_EVSTDH:
10598 case SPE_BUILTIN_EVSTDW:
10599 case SPE_BUILTIN_EVSTWHE:
10600 case SPE_BUILTIN_EVSTWHO:
10601 case SPE_BUILTIN_EVSTWWE:
10602 case SPE_BUILTIN_EVSTWWO:
10603 arg1 = CALL_EXPR_ARG (exp, 2);
10604 if (TREE_CODE (arg1) != INTEGER_CST
10605 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10607 error ("argument 2 must be a 5-bit unsigned literal");
10615 /* The evsplat*i instructions are not quite generic. */
10618 case SPE_BUILTIN_EVSPLATFI:
10619 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10621 case SPE_BUILTIN_EVSPLATI:
10622 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10628 d = (struct builtin_description *) bdesc_2arg_spe;
10629 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10630 if (d->code == fcode)
10631 return rs6000_expand_binop_builtin (d->icode, exp, target);
10633 d = (struct builtin_description *) bdesc_spe_predicates;
10634 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10635 if (d->code == fcode)
10636 return spe_expand_predicate_builtin (d->icode, exp, target);
10638 d = (struct builtin_description *) bdesc_spe_evsel;
10639 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10640 if (d->code == fcode)
10641 return spe_expand_evsel_builtin (d->icode, exp, target);
10645 case SPE_BUILTIN_EVSTDDX:
10646 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10647 case SPE_BUILTIN_EVSTDHX:
10648 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10649 case SPE_BUILTIN_EVSTDWX:
10650 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10651 case SPE_BUILTIN_EVSTWHEX:
10652 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10653 case SPE_BUILTIN_EVSTWHOX:
10654 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10655 case SPE_BUILTIN_EVSTWWEX:
10656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10657 case SPE_BUILTIN_EVSTWWOX:
10658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10659 case SPE_BUILTIN_EVSTDD:
10660 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10661 case SPE_BUILTIN_EVSTDH:
10662 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10663 case SPE_BUILTIN_EVSTDW:
10664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10665 case SPE_BUILTIN_EVSTWHE:
10666 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10667 case SPE_BUILTIN_EVSTWHO:
10668 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10669 case SPE_BUILTIN_EVSTWWE:
10670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10671 case SPE_BUILTIN_EVSTWWO:
10672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10673 case SPE_BUILTIN_MFSPEFSCR:
10674 icode = CODE_FOR_spe_mfspefscr;
10675 tmode = insn_data[icode].operand[0].mode;
10678 || GET_MODE (target) != tmode
10679 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10680 target = gen_reg_rtx (tmode);
10682 pat = GEN_FCN (icode) (target);
10687 case SPE_BUILTIN_MTSPEFSCR:
10688 icode = CODE_FOR_spe_mtspefscr;
10689 arg0 = CALL_EXPR_ARG (exp, 0);
10690 op0 = expand_normal (arg0);
10691 mode0 = insn_data[icode].operand[0].mode;
10693 if (arg0 == error_mark_node)
10696 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10697 op0 = copy_to_mode_reg (mode0, op0);
10699 pat = GEN_FCN (icode) (op0);
10707 *expandedp = false;
10712 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10714 rtx pat, scratch, tmp;
10715 tree form = CALL_EXPR_ARG (exp, 0);
10716 tree arg0 = CALL_EXPR_ARG (exp, 1);
10717 tree arg1 = CALL_EXPR_ARG (exp, 2);
10718 rtx op0 = expand_normal (arg0);
10719 rtx op1 = expand_normal (arg1);
10720 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10721 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10723 enum rtx_code code;
10725 if (TREE_CODE (form) != INTEGER_CST)
10727 error ("argument 1 of __builtin_paired_predicate must be a constant");
10731 form_int = TREE_INT_CST_LOW (form);
10733 gcc_assert (mode0 == mode1);
10735 if (arg0 == error_mark_node || arg1 == error_mark_node)
10739 || GET_MODE (target) != SImode
10740 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10741 target = gen_reg_rtx (SImode);
10742 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10743 op0 = copy_to_mode_reg (mode0, op0);
10744 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10745 op1 = copy_to_mode_reg (mode1, op1);
10747 scratch = gen_reg_rtx (CCFPmode);
10749 pat = GEN_FCN (icode) (scratch, op0, op1);
10771 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10774 error ("argument 1 of __builtin_paired_predicate is out of range");
10778 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10779 emit_move_insn (target, tmp);
10784 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10786 rtx pat, scratch, tmp;
10787 tree form = CALL_EXPR_ARG (exp, 0);
10788 tree arg0 = CALL_EXPR_ARG (exp, 1);
10789 tree arg1 = CALL_EXPR_ARG (exp, 2);
10790 rtx op0 = expand_normal (arg0);
10791 rtx op1 = expand_normal (arg1);
10792 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10793 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10795 enum rtx_code code;
10797 if (TREE_CODE (form) != INTEGER_CST)
10799 error ("argument 1 of __builtin_spe_predicate must be a constant");
10803 form_int = TREE_INT_CST_LOW (form);
10805 gcc_assert (mode0 == mode1);
10807 if (arg0 == error_mark_node || arg1 == error_mark_node)
10811 || GET_MODE (target) != SImode
10812 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10813 target = gen_reg_rtx (SImode);
10815 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10816 op0 = copy_to_mode_reg (mode0, op0);
10817 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10818 op1 = copy_to_mode_reg (mode1, op1);
10820 scratch = gen_reg_rtx (CCmode);
10822 pat = GEN_FCN (icode) (scratch, op0, op1);
10827 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10828 _lower_. We use one compare, but look in different bits of the
10829 CR for each variant.
10831 There are 2 elements in each SPE simd type (upper/lower). The CR
10832 bits are set as follows:
10834 BIT0 | BIT 1 | BIT 2 | BIT 3
10835 U | L | (U | L) | (U & L)
10837 So, for an "all" relationship, BIT 3 would be set.
10838 For an "any" relationship, BIT 2 would be set. Etc.
10840 Following traditional nomenclature, these bits map to:
10842 BIT0 | BIT 1 | BIT 2 | BIT 3
10845 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10850 /* All variant. OV bit. */
10852 /* We need to get to the OV bit, which is the ORDERED bit. We
10853 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10854 that's ugly and will make validate_condition_mode die.
10855 So let's just use another pattern. */
10856 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10858 /* Any variant. EQ bit. */
10862 /* Upper variant. LT bit. */
10866 /* Lower variant. GT bit. */
10871 error ("argument 1 of __builtin_spe_predicate is out of range");
10875 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10876 emit_move_insn (target, tmp);
10881 /* The evsel builtins look like this:
10883 e = __builtin_spe_evsel_OP (a, b, c, d);
10885 and work like this:
10887 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10888 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10892 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10895 tree arg0 = CALL_EXPR_ARG (exp, 0);
10896 tree arg1 = CALL_EXPR_ARG (exp, 1);
10897 tree arg2 = CALL_EXPR_ARG (exp, 2);
10898 tree arg3 = CALL_EXPR_ARG (exp, 3);
10899 rtx op0 = expand_normal (arg0);
10900 rtx op1 = expand_normal (arg1);
10901 rtx op2 = expand_normal (arg2);
10902 rtx op3 = expand_normal (arg3);
10903 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10904 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10906 gcc_assert (mode0 == mode1);
10908 if (arg0 == error_mark_node || arg1 == error_mark_node
10909 || arg2 == error_mark_node || arg3 == error_mark_node)
10913 || GET_MODE (target) != mode0
10914 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10915 target = gen_reg_rtx (mode0);
10917 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10918 op0 = copy_to_mode_reg (mode0, op0);
10919 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10920 op1 = copy_to_mode_reg (mode0, op1);
10921 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10922 op2 = copy_to_mode_reg (mode0, op2);
10923 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10924 op3 = copy_to_mode_reg (mode0, op3);
10926 /* Generate the compare. */
10927 scratch = gen_reg_rtx (CCmode);
10928 pat = GEN_FCN (icode) (scratch, op0, op1);
10933 if (mode0 == V2SImode)
10934 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10936 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10941 /* Expand an expression EXP that calls a built-in function,
10942 with result going to TARGET if that's convenient
10943 (and in mode MODE if that's convenient).
10944 SUBTARGET may be used as the target for computing one of EXP's operands.
10945 IGNORE is nonzero if the value is to be ignored. */
10948 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10949 enum machine_mode mode ATTRIBUTE_UNUSED,
10950 int ignore ATTRIBUTE_UNUSED)
10952 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10953 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10954 const struct builtin_description *d;
10959 if (fcode == RS6000_BUILTIN_RECIP)
10960 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10962 if (fcode == RS6000_BUILTIN_RECIPF)
10963 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10965 if (fcode == RS6000_BUILTIN_RSQRTF)
10966 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10968 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10969 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10971 if (fcode == POWER7_BUILTIN_BPERMD)
10972 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10973 ? CODE_FOR_bpermd_di
10974 : CODE_FOR_bpermd_si), exp, target);
10976 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10977 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10979 int icode = (int) CODE_FOR_altivec_lvsr;
10980 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10981 enum machine_mode mode = insn_data[icode].operand[1].mode;
10985 gcc_assert (TARGET_ALTIVEC);
10987 arg = CALL_EXPR_ARG (exp, 0);
10988 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10989 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10990 addr = memory_address (mode, op);
10991 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10995 /* For the load case need to negate the address. */
10996 op = gen_reg_rtx (GET_MODE (addr));
10997 emit_insn (gen_rtx_SET (VOIDmode, op,
10998 gen_rtx_NEG (GET_MODE (addr), addr)));
11000 op = gen_rtx_MEM (mode, op);
11003 || GET_MODE (target) != tmode
11004 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11005 target = gen_reg_rtx (tmode);
11007 /*pat = gen_altivec_lvsr (target, op);*/
11008 pat = GEN_FCN (icode) (target, op);
11016 /* FIXME: There's got to be a nicer way to handle this case than
11017 constructing a new CALL_EXPR. */
11018 if (fcode == ALTIVEC_BUILTIN_VCFUX
11019 || fcode == ALTIVEC_BUILTIN_VCFSX
11020 || fcode == ALTIVEC_BUILTIN_VCTUXS
11021 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11023 if (call_expr_nargs (exp) == 1)
11024 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11025 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11028 if (TARGET_ALTIVEC)
11030 ret = altivec_expand_builtin (exp, target, &success);
11037 ret = spe_expand_builtin (exp, target, &success);
11042 if (TARGET_PAIRED_FLOAT)
11044 ret = paired_expand_builtin (exp, target, &success);
11050 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11052 /* Handle simple unary operations. */
11053 d = (struct builtin_description *) bdesc_1arg;
11054 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11055 if (d->code == fcode)
11056 return rs6000_expand_unop_builtin (d->icode, exp, target);
11058 /* Handle simple binary operations. */
11059 d = (struct builtin_description *) bdesc_2arg;
11060 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11061 if (d->code == fcode)
11062 return rs6000_expand_binop_builtin (d->icode, exp, target);
11064 /* Handle simple ternary operations. */
11066 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11067 if (d->code == fcode)
11068 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11070 gcc_unreachable ();
11074 rs6000_init_builtins (void)
11078 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11079 V2SF_type_node = build_vector_type (float_type_node, 2);
11080 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11081 V2DF_type_node = build_vector_type (double_type_node, 2);
11082 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11083 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11084 V4SF_type_node = build_vector_type (float_type_node, 4);
11085 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11086 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11088 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11089 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11090 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11091 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11093 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11094 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11095 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11096 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11098 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11099 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11100 'vector unsigned short'. */
11102 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11103 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11104 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11105 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11106 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11108 long_integer_type_internal_node = long_integer_type_node;
11109 long_unsigned_type_internal_node = long_unsigned_type_node;
11110 intQI_type_internal_node = intQI_type_node;
11111 uintQI_type_internal_node = unsigned_intQI_type_node;
11112 intHI_type_internal_node = intHI_type_node;
11113 uintHI_type_internal_node = unsigned_intHI_type_node;
11114 intSI_type_internal_node = intSI_type_node;
11115 uintSI_type_internal_node = unsigned_intSI_type_node;
11116 intDI_type_internal_node = intDI_type_node;
11117 uintDI_type_internal_node = unsigned_intDI_type_node;
11118 float_type_internal_node = float_type_node;
11119 double_type_internal_node = float_type_node;
11120 void_type_internal_node = void_type_node;
11122 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11124 builtin_mode_to_type[QImode][0] = integer_type_node;
11125 builtin_mode_to_type[HImode][0] = integer_type_node;
11126 builtin_mode_to_type[SImode][0] = intSI_type_node;
11127 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11128 builtin_mode_to_type[DImode][0] = intDI_type_node;
11129 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11130 builtin_mode_to_type[SFmode][0] = float_type_node;
11131 builtin_mode_to_type[DFmode][0] = double_type_node;
11132 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11133 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11134 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11135 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11136 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11137 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11138 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11139 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11140 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11141 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11142 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11143 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11144 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11146 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11147 get_identifier ("__bool char"),
11148 bool_char_type_node);
11149 TYPE_NAME (bool_char_type_node) = tdecl;
11150 (*lang_hooks.decls.pushdecl) (tdecl);
11151 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11152 get_identifier ("__bool short"),
11153 bool_short_type_node);
11154 TYPE_NAME (bool_short_type_node) = tdecl;
11155 (*lang_hooks.decls.pushdecl) (tdecl);
11156 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11157 get_identifier ("__bool int"),
11158 bool_int_type_node);
11159 TYPE_NAME (bool_int_type_node) = tdecl;
11160 (*lang_hooks.decls.pushdecl) (tdecl);
11161 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11163 TYPE_NAME (pixel_type_node) = tdecl;
11164 (*lang_hooks.decls.pushdecl) (tdecl);
11166 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11167 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11168 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11169 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11170 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11172 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11173 get_identifier ("__vector unsigned char"),
11174 unsigned_V16QI_type_node);
11175 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11176 (*lang_hooks.decls.pushdecl) (tdecl);
11177 tdecl = build_decl (BUILTINS_LOCATION,
11178 TYPE_DECL, get_identifier ("__vector signed char"),
11180 TYPE_NAME (V16QI_type_node) = tdecl;
11181 (*lang_hooks.decls.pushdecl) (tdecl);
11182 tdecl = build_decl (BUILTINS_LOCATION,
11183 TYPE_DECL, get_identifier ("__vector __bool char"),
11184 bool_V16QI_type_node);
11185 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11186 (*lang_hooks.decls.pushdecl) (tdecl);
11188 tdecl = build_decl (BUILTINS_LOCATION,
11189 TYPE_DECL, get_identifier ("__vector unsigned short"),
11190 unsigned_V8HI_type_node);
11191 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11192 (*lang_hooks.decls.pushdecl) (tdecl);
11193 tdecl = build_decl (BUILTINS_LOCATION,
11194 TYPE_DECL, get_identifier ("__vector signed short"),
11196 TYPE_NAME (V8HI_type_node) = tdecl;
11197 (*lang_hooks.decls.pushdecl) (tdecl);
11198 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11199 get_identifier ("__vector __bool short"),
11200 bool_V8HI_type_node);
11201 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11202 (*lang_hooks.decls.pushdecl) (tdecl);
11204 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11205 get_identifier ("__vector unsigned int"),
11206 unsigned_V4SI_type_node);
11207 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11208 (*lang_hooks.decls.pushdecl) (tdecl);
11209 tdecl = build_decl (BUILTINS_LOCATION,
11210 TYPE_DECL, get_identifier ("__vector signed int"),
11212 TYPE_NAME (V4SI_type_node) = tdecl;
11213 (*lang_hooks.decls.pushdecl) (tdecl);
11214 tdecl = build_decl (BUILTINS_LOCATION,
11215 TYPE_DECL, get_identifier ("__vector __bool int"),
11216 bool_V4SI_type_node);
11217 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11218 (*lang_hooks.decls.pushdecl) (tdecl);
11220 tdecl = build_decl (BUILTINS_LOCATION,
11221 TYPE_DECL, get_identifier ("__vector float"),
11223 TYPE_NAME (V4SF_type_node) = tdecl;
11224 (*lang_hooks.decls.pushdecl) (tdecl);
11225 tdecl = build_decl (BUILTINS_LOCATION,
11226 TYPE_DECL, get_identifier ("__vector __pixel"),
11227 pixel_V8HI_type_node);
11228 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11229 (*lang_hooks.decls.pushdecl) (tdecl);
11233 tdecl = build_decl (BUILTINS_LOCATION,
11234 TYPE_DECL, get_identifier ("__vector double"),
11236 TYPE_NAME (V2DF_type_node) = tdecl;
11237 (*lang_hooks.decls.pushdecl) (tdecl);
11239 tdecl = build_decl (BUILTINS_LOCATION,
11240 TYPE_DECL, get_identifier ("__vector long"),
11242 TYPE_NAME (V2DI_type_node) = tdecl;
11243 (*lang_hooks.decls.pushdecl) (tdecl);
11245 tdecl = build_decl (BUILTINS_LOCATION,
11246 TYPE_DECL, get_identifier ("__vector unsigned long"),
11247 unsigned_V2DI_type_node);
11248 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11249 (*lang_hooks.decls.pushdecl) (tdecl);
11251 tdecl = build_decl (BUILTINS_LOCATION,
11252 TYPE_DECL, get_identifier ("__vector __bool long"),
11253 bool_V2DI_type_node);
11254 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11255 (*lang_hooks.decls.pushdecl) (tdecl);
11258 if (TARGET_PAIRED_FLOAT)
11259 paired_init_builtins ();
11261 spe_init_builtins ();
11262 if (TARGET_ALTIVEC)
11263 altivec_init_builtins ();
11264 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11265 rs6000_common_init_builtins ();
11266 if (TARGET_PPC_GFXOPT)
11268 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11269 RS6000_BUILTIN_RECIPF,
11270 "__builtin_recipdivf");
11271 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11272 RS6000_BUILTIN_RECIPF);
11274 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11275 RS6000_BUILTIN_RSQRTF,
11276 "__builtin_rsqrtf");
11277 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11278 RS6000_BUILTIN_RSQRTF);
11280 if (TARGET_POPCNTB)
11282 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11283 RS6000_BUILTIN_RECIP,
11284 "__builtin_recipdiv");
11285 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11286 RS6000_BUILTIN_RECIP);
11289 if (TARGET_POPCNTD)
11291 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11292 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11293 POWER7_BUILTIN_BPERMD,
11294 "__builtin_bpermd");
11295 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11296 POWER7_BUILTIN_BPERMD);
11298 if (TARGET_POWERPC)
11300 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11301 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11302 unsigned_intHI_type_node,
11304 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11305 RS6000_BUILTIN_BSWAP_HI);
11309 /* AIX libm provides clog as __clog. */
11310 if (built_in_decls [BUILT_IN_CLOG])
11311 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11314 #ifdef SUBTARGET_INIT_BUILTINS
11315 SUBTARGET_INIT_BUILTINS;
11319 /* Returns the rs6000 builtin decl for CODE. */
11322 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11324 if (code >= RS6000_BUILTIN_COUNT)
11325 return error_mark_node;
11327 return rs6000_builtin_decls[code];
11330 /* Search through a set of builtins and enable the mask bits.
11331 DESC is an array of builtins.
11332 SIZE is the total number of builtins.
11333 START is the builtin enum at which to start.
11334 END is the builtin enum at which to end. */
11336 enable_mask_for_builtins (struct builtin_description *desc, int size,
11337 enum rs6000_builtins start,
11338 enum rs6000_builtins end)
11342 for (i = 0; i < size; ++i)
11343 if (desc[i].code == start)
11349 for (; i < size; ++i)
11351 /* Flip all the bits on. */
11352 desc[i].mask = target_flags;
11353 if (desc[i].code == end)
11359 spe_init_builtins (void)
11361 tree endlink = void_list_node;
11362 tree puint_type_node = build_pointer_type (unsigned_type_node);
11363 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11364 struct builtin_description *d;
11367 tree v2si_ftype_4_v2si
11368 = build_function_type
11369 (opaque_V2SI_type_node,
11370 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11371 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11372 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11373 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11376 tree v2sf_ftype_4_v2sf
11377 = build_function_type
11378 (opaque_V2SF_type_node,
11379 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11380 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11381 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11382 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11385 tree int_ftype_int_v2si_v2si
11386 = build_function_type
11387 (integer_type_node,
11388 tree_cons (NULL_TREE, integer_type_node,
11389 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11390 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11393 tree int_ftype_int_v2sf_v2sf
11394 = build_function_type
11395 (integer_type_node,
11396 tree_cons (NULL_TREE, integer_type_node,
11397 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11398 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11401 tree void_ftype_v2si_puint_int
11402 = build_function_type (void_type_node,
11403 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11404 tree_cons (NULL_TREE, puint_type_node,
11405 tree_cons (NULL_TREE,
11409 tree void_ftype_v2si_puint_char
11410 = build_function_type (void_type_node,
11411 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11412 tree_cons (NULL_TREE, puint_type_node,
11413 tree_cons (NULL_TREE,
11417 tree void_ftype_v2si_pv2si_int
11418 = build_function_type (void_type_node,
11419 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11420 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11421 tree_cons (NULL_TREE,
11425 tree void_ftype_v2si_pv2si_char
11426 = build_function_type (void_type_node,
11427 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11428 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11429 tree_cons (NULL_TREE,
11433 tree void_ftype_int
11434 = build_function_type (void_type_node,
11435 tree_cons (NULL_TREE, integer_type_node, endlink));
11437 tree int_ftype_void
11438 = build_function_type (integer_type_node, endlink);
11440 tree v2si_ftype_pv2si_int
11441 = build_function_type (opaque_V2SI_type_node,
11442 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11443 tree_cons (NULL_TREE, integer_type_node,
11446 tree v2si_ftype_puint_int
11447 = build_function_type (opaque_V2SI_type_node,
11448 tree_cons (NULL_TREE, puint_type_node,
11449 tree_cons (NULL_TREE, integer_type_node,
11452 tree v2si_ftype_pushort_int
11453 = build_function_type (opaque_V2SI_type_node,
11454 tree_cons (NULL_TREE, pushort_type_node,
11455 tree_cons (NULL_TREE, integer_type_node,
11458 tree v2si_ftype_signed_char
11459 = build_function_type (opaque_V2SI_type_node,
11460 tree_cons (NULL_TREE, signed_char_type_node,
11463 /* The initialization of the simple binary and unary builtins is
11464 done in rs6000_common_init_builtins, but we have to enable the
11465 mask bits here manually because we have run out of `target_flags'
11466 bits. We really need to redesign this mask business. */
11468 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11469 ARRAY_SIZE (bdesc_2arg),
11470 SPE_BUILTIN_EVADDW,
11471 SPE_BUILTIN_EVXOR);
11472 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11473 ARRAY_SIZE (bdesc_1arg),
11475 SPE_BUILTIN_EVSUBFUSIAAW);
11476 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11477 ARRAY_SIZE (bdesc_spe_predicates),
11478 SPE_BUILTIN_EVCMPEQ,
11479 SPE_BUILTIN_EVFSTSTLT);
11480 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11481 ARRAY_SIZE (bdesc_spe_evsel),
11482 SPE_BUILTIN_EVSEL_CMPGTS,
11483 SPE_BUILTIN_EVSEL_FSTSTEQ);
11485 (*lang_hooks.decls.pushdecl)
11486 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11487 get_identifier ("__ev64_opaque__"),
11488 opaque_V2SI_type_node));
11490 /* Initialize irregular SPE builtins. */
11492 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11493 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11494 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11495 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11496 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11497 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11498 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11499 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11500 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11501 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11502 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11503 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11504 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11505 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11506 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11507 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11508 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11509 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11512 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11513 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11514 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11515 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11516 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11517 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11518 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11519 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11520 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11521 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11522 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11523 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11524 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11525 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11526 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11527 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11528 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11529 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11530 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11531 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11532 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11533 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11536 d = (struct builtin_description *) bdesc_spe_predicates;
11537 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11541 switch (insn_data[d->icode].operand[1].mode)
11544 type = int_ftype_int_v2si_v2si;
11547 type = int_ftype_int_v2sf_v2sf;
11550 gcc_unreachable ();
11553 def_builtin (d->mask, d->name, type, d->code);
11556 /* Evsel predicates. */
11557 d = (struct builtin_description *) bdesc_spe_evsel;
11558 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11562 switch (insn_data[d->icode].operand[1].mode)
11565 type = v2si_ftype_4_v2si;
11568 type = v2sf_ftype_4_v2sf;
11571 gcc_unreachable ();
11574 def_builtin (d->mask, d->name, type, d->code);
11579 paired_init_builtins (void)
11581 const struct builtin_description *d;
11583 tree endlink = void_list_node;
11585 tree int_ftype_int_v2sf_v2sf
11586 = build_function_type
11587 (integer_type_node,
11588 tree_cons (NULL_TREE, integer_type_node,
11589 tree_cons (NULL_TREE, V2SF_type_node,
11590 tree_cons (NULL_TREE, V2SF_type_node,
11592 tree pcfloat_type_node =
11593 build_pointer_type (build_qualified_type
11594 (float_type_node, TYPE_QUAL_CONST));
11596 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11597 long_integer_type_node,
11600 tree void_ftype_v2sf_long_pcfloat =
11601 build_function_type_list (void_type_node,
11603 long_integer_type_node,
11608 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11609 PAIRED_BUILTIN_LX);
11612 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11613 PAIRED_BUILTIN_STX);
11616 d = bdesc_paired_preds;
11617 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11621 switch (insn_data[d->icode].operand[1].mode)
11624 type = int_ftype_int_v2sf_v2sf;
11627 gcc_unreachable ();
11630 def_builtin (d->mask, d->name, type, d->code);
11635 altivec_init_builtins (void)
11637 const struct builtin_description *d;
11638 const struct builtin_description_predicates *dp;
11642 tree pfloat_type_node = build_pointer_type (float_type_node);
11643 tree pint_type_node = build_pointer_type (integer_type_node);
11644 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11645 tree pchar_type_node = build_pointer_type (char_type_node);
11647 tree pvoid_type_node = build_pointer_type (void_type_node);
11649 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11650 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11651 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11652 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11654 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11656 tree int_ftype_opaque
11657 = build_function_type_list (integer_type_node,
11658 opaque_V4SI_type_node, NULL_TREE);
11659 tree opaque_ftype_opaque
11660 = build_function_type (integer_type_node,
11662 tree opaque_ftype_opaque_int
11663 = build_function_type_list (opaque_V4SI_type_node,
11664 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11665 tree opaque_ftype_opaque_opaque_int
11666 = build_function_type_list (opaque_V4SI_type_node,
11667 opaque_V4SI_type_node, opaque_V4SI_type_node,
11668 integer_type_node, NULL_TREE);
11669 tree int_ftype_int_opaque_opaque
11670 = build_function_type_list (integer_type_node,
11671 integer_type_node, opaque_V4SI_type_node,
11672 opaque_V4SI_type_node, NULL_TREE);
11673 tree int_ftype_int_v4si_v4si
11674 = build_function_type_list (integer_type_node,
11675 integer_type_node, V4SI_type_node,
11676 V4SI_type_node, NULL_TREE);
11677 tree v4sf_ftype_pcfloat
11678 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11679 tree void_ftype_pfloat_v4sf
11680 = build_function_type_list (void_type_node,
11681 pfloat_type_node, V4SF_type_node, NULL_TREE);
11682 tree v4si_ftype_pcint
11683 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11684 tree void_ftype_pint_v4si
11685 = build_function_type_list (void_type_node,
11686 pint_type_node, V4SI_type_node, NULL_TREE);
11687 tree v8hi_ftype_pcshort
11688 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11689 tree void_ftype_pshort_v8hi
11690 = build_function_type_list (void_type_node,
11691 pshort_type_node, V8HI_type_node, NULL_TREE);
11692 tree v16qi_ftype_pcchar
11693 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11694 tree void_ftype_pchar_v16qi
11695 = build_function_type_list (void_type_node,
11696 pchar_type_node, V16QI_type_node, NULL_TREE);
11697 tree void_ftype_v4si
11698 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11699 tree v8hi_ftype_void
11700 = build_function_type (V8HI_type_node, void_list_node);
11701 tree void_ftype_void
11702 = build_function_type (void_type_node, void_list_node);
11703 tree void_ftype_int
11704 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11706 tree opaque_ftype_long_pcvoid
11707 = build_function_type_list (opaque_V4SI_type_node,
11708 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11709 tree v16qi_ftype_long_pcvoid
11710 = build_function_type_list (V16QI_type_node,
11711 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11712 tree v8hi_ftype_long_pcvoid
11713 = build_function_type_list (V8HI_type_node,
11714 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11715 tree v4si_ftype_long_pcvoid
11716 = build_function_type_list (V4SI_type_node,
11717 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11719 tree void_ftype_opaque_long_pvoid
11720 = build_function_type_list (void_type_node,
11721 opaque_V4SI_type_node, long_integer_type_node,
11722 pvoid_type_node, NULL_TREE);
11723 tree void_ftype_v4si_long_pvoid
11724 = build_function_type_list (void_type_node,
11725 V4SI_type_node, long_integer_type_node,
11726 pvoid_type_node, NULL_TREE);
11727 tree void_ftype_v16qi_long_pvoid
11728 = build_function_type_list (void_type_node,
11729 V16QI_type_node, long_integer_type_node,
11730 pvoid_type_node, NULL_TREE);
11731 tree void_ftype_v8hi_long_pvoid
11732 = build_function_type_list (void_type_node,
11733 V8HI_type_node, long_integer_type_node,
11734 pvoid_type_node, NULL_TREE);
11735 tree int_ftype_int_v8hi_v8hi
11736 = build_function_type_list (integer_type_node,
11737 integer_type_node, V8HI_type_node,
11738 V8HI_type_node, NULL_TREE);
11739 tree int_ftype_int_v16qi_v16qi
11740 = build_function_type_list (integer_type_node,
11741 integer_type_node, V16QI_type_node,
11742 V16QI_type_node, NULL_TREE);
11743 tree int_ftype_int_v4sf_v4sf
11744 = build_function_type_list (integer_type_node,
11745 integer_type_node, V4SF_type_node,
11746 V4SF_type_node, NULL_TREE);
11747 tree int_ftype_int_v2df_v2df
11748 = build_function_type_list (integer_type_node,
11749 integer_type_node, V2DF_type_node,
11750 V2DF_type_node, NULL_TREE);
11751 tree v4si_ftype_v4si
11752 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11753 tree v8hi_ftype_v8hi
11754 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11755 tree v16qi_ftype_v16qi
11756 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11757 tree v4sf_ftype_v4sf
11758 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11759 tree v2df_ftype_v2df
11760 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11761 tree void_ftype_pcvoid_int_int
11762 = build_function_type_list (void_type_node,
11763 pcvoid_type_node, integer_type_node,
11764 integer_type_node, NULL_TREE);
11766 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11767 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11768 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11769 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11770 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11771 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11772 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11773 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11774 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11775 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11776 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11777 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11778 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11779 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11781 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11783 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11785 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11787 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11798 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11799 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11800 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11801 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11802 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11804 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11805 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11807 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11808 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11810 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11811 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11813 if (rs6000_cpu == PROCESSOR_CELL)
11815 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11816 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11817 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11818 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11820 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11825 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11826 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11827 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11828 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11830 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11831 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11832 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11833 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11835 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11836 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11839 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11840 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11841 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11842 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11843 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11844 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11845 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11850 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11852 /* Add the DST variants. */
11854 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11855 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11857 /* Initialize the predicates. */
11858 dp = bdesc_altivec_preds;
11859 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11861 enum machine_mode mode1;
11863 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11864 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11865 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11866 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11871 mode1 = insn_data[dp->icode].operand[1].mode;
11876 type = int_ftype_int_opaque_opaque;
11879 type = int_ftype_int_v4si_v4si;
11882 type = int_ftype_int_v8hi_v8hi;
11885 type = int_ftype_int_v16qi_v16qi;
11888 type = int_ftype_int_v4sf_v4sf;
11891 type = int_ftype_int_v2df_v2df;
11894 gcc_unreachable ();
11897 def_builtin (dp->mask, dp->name, type, dp->code);
11900 /* Initialize the abs* operators. */
11902 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11904 enum machine_mode mode0;
11907 mode0 = insn_data[d->icode].operand[0].mode;
11912 type = v4si_ftype_v4si;
11915 type = v8hi_ftype_v8hi;
11918 type = v16qi_ftype_v16qi;
11921 type = v4sf_ftype_v4sf;
11924 type = v2df_ftype_v2df;
11927 gcc_unreachable ();
11930 def_builtin (d->mask, d->name, type, d->code);
11933 if (TARGET_ALTIVEC)
11937 /* Initialize target builtin that implements
11938 targetm.vectorize.builtin_mask_for_load. */
11940 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11941 v16qi_ftype_long_pcvoid,
11942 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11943 BUILT_IN_MD, NULL, NULL_TREE);
11944 TREE_READONLY (decl) = 1;
11945 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11946 altivec_builtin_mask_for_load = decl;
11949 /* Access to the vec_init patterns. */
11950 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11951 integer_type_node, integer_type_node,
11952 integer_type_node, NULL_TREE);
11953 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11954 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11956 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11957 short_integer_type_node,
11958 short_integer_type_node,
11959 short_integer_type_node,
11960 short_integer_type_node,
11961 short_integer_type_node,
11962 short_integer_type_node,
11963 short_integer_type_node, NULL_TREE);
11964 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11965 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11967 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11968 char_type_node, char_type_node,
11969 char_type_node, char_type_node,
11970 char_type_node, char_type_node,
11971 char_type_node, char_type_node,
11972 char_type_node, char_type_node,
11973 char_type_node, char_type_node,
11974 char_type_node, char_type_node,
11975 char_type_node, NULL_TREE);
11976 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11977 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11979 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11980 float_type_node, float_type_node,
11981 float_type_node, NULL_TREE);
11982 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11983 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11987 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11988 double_type_node, NULL_TREE);
11989 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11990 VSX_BUILTIN_VEC_INIT_V2DF);
11992 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11993 intDI_type_node, NULL_TREE);
11994 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11995 VSX_BUILTIN_VEC_INIT_V2DI);
11998 /* Access to the vec_set patterns. */
11999 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12001 integer_type_node, NULL_TREE);
12002 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12003 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12005 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12007 integer_type_node, NULL_TREE);
12008 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12009 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12011 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12013 integer_type_node, NULL_TREE);
12014 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12015 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12017 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12019 integer_type_node, NULL_TREE);
12020 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12021 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12025 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12027 integer_type_node, NULL_TREE);
12028 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12029 VSX_BUILTIN_VEC_SET_V2DF);
12031 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12033 integer_type_node, NULL_TREE);
12034 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12035 VSX_BUILTIN_VEC_SET_V2DI);
12038 /* Access to the vec_extract patterns. */
12039 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12040 integer_type_node, NULL_TREE);
12041 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12042 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12044 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12045 integer_type_node, NULL_TREE);
12046 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12047 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12049 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12050 integer_type_node, NULL_TREE);
12051 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12052 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12054 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12055 integer_type_node, NULL_TREE);
12056 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12057 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12061 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12062 integer_type_node, NULL_TREE);
12063 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12064 VSX_BUILTIN_VEC_EXT_V2DF);
12066 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12067 integer_type_node, NULL_TREE);
12068 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12069 VSX_BUILTIN_VEC_EXT_V2DI);
12073 /* Hash function for builtin functions with up to 3 arguments and a return
12076 builtin_hash_function (const void *hash_entry)
12080 const struct builtin_hash_struct *bh =
12081 (const struct builtin_hash_struct *) hash_entry;
12083 for (i = 0; i < 4; i++)
12085 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12086 ret = (ret * 2) + bh->uns_p[i];
12092 /* Compare builtin hash entries H1 and H2 for equivalence. */
12094 builtin_hash_eq (const void *h1, const void *h2)
12096 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12097 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12099 return ((p1->mode[0] == p2->mode[0])
12100 && (p1->mode[1] == p2->mode[1])
12101 && (p1->mode[2] == p2->mode[2])
12102 && (p1->mode[3] == p2->mode[3])
12103 && (p1->uns_p[0] == p2->uns_p[0])
12104 && (p1->uns_p[1] == p2->uns_p[1])
12105 && (p1->uns_p[2] == p2->uns_p[2])
12106 && (p1->uns_p[3] == p2->uns_p[3]));
12109 /* Map types for builtin functions with an explicit return type and up to 3
12110 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12111 of the argument. */
12113 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12114 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12115 enum rs6000_builtins builtin, const char *name)
12117 struct builtin_hash_struct h;
12118 struct builtin_hash_struct *h2;
12122 tree ret_type = NULL_TREE;
12123 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12126 /* Create builtin_hash_table. */
12127 if (builtin_hash_table == NULL)
12128 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12129 builtin_hash_eq, NULL);
12131 h.type = NULL_TREE;
12132 h.mode[0] = mode_ret;
12133 h.mode[1] = mode_arg0;
12134 h.mode[2] = mode_arg1;
12135 h.mode[3] = mode_arg2;
12141 /* If the builtin is a type that produces unsigned results or takes unsigned
12142 arguments, and it is returned as a decl for the vectorizer (such as
12143 widening multiplies, permute), make sure the arguments and return value
12144 are type correct. */
12147 /* unsigned 2 argument functions. */
12148 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12149 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12150 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12151 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12157 /* unsigned 3 argument functions. */
12158 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12159 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12160 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12161 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12162 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12163 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12164 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12165 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12166 case VSX_BUILTIN_VPERM_16QI_UNS:
12167 case VSX_BUILTIN_VPERM_8HI_UNS:
12168 case VSX_BUILTIN_VPERM_4SI_UNS:
12169 case VSX_BUILTIN_VPERM_2DI_UNS:
12170 case VSX_BUILTIN_XXSEL_16QI_UNS:
12171 case VSX_BUILTIN_XXSEL_8HI_UNS:
12172 case VSX_BUILTIN_XXSEL_4SI_UNS:
12173 case VSX_BUILTIN_XXSEL_2DI_UNS:
12180 /* signed permute functions with unsigned char mask. */
12181 case ALTIVEC_BUILTIN_VPERM_16QI:
12182 case ALTIVEC_BUILTIN_VPERM_8HI:
12183 case ALTIVEC_BUILTIN_VPERM_4SI:
12184 case ALTIVEC_BUILTIN_VPERM_4SF:
12185 case ALTIVEC_BUILTIN_VPERM_2DI:
12186 case ALTIVEC_BUILTIN_VPERM_2DF:
12187 case VSX_BUILTIN_VPERM_16QI:
12188 case VSX_BUILTIN_VPERM_8HI:
12189 case VSX_BUILTIN_VPERM_4SI:
12190 case VSX_BUILTIN_VPERM_4SF:
12191 case VSX_BUILTIN_VPERM_2DI:
12192 case VSX_BUILTIN_VPERM_2DF:
12196 /* unsigned args, signed return. */
12197 case VSX_BUILTIN_XVCVUXDDP_UNS:
12198 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12202 /* signed args, unsigned return. */
12203 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12204 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12212 /* Figure out how many args are present. */
12213 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12217 fatal_error ("internal error: builtin function %s had no type", name);
12219 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12220 if (!ret_type && h.uns_p[0])
12221 ret_type = builtin_mode_to_type[h.mode[0]][0];
12224 fatal_error ("internal error: builtin function %s had an unexpected "
12225 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12227 for (i = 0; i < num_args; i++)
12229 int m = (int) h.mode[i+1];
12230 int uns_p = h.uns_p[i+1];
12232 arg_type[i] = builtin_mode_to_type[m][uns_p];
12233 if (!arg_type[i] && uns_p)
12234 arg_type[i] = builtin_mode_to_type[m][0];
12237 fatal_error ("internal error: builtin function %s, argument %d "
12238 "had unexpected argument type %s", name, i,
12239 GET_MODE_NAME (m));
12242 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12243 if (*found == NULL)
12245 h2 = GGC_NEW (struct builtin_hash_struct);
12247 *found = (void *)h2;
12248 args = void_list_node;
12250 for (i = num_args - 1; i >= 0; i--)
12251 args = tree_cons (NULL_TREE, arg_type[i], args);
12253 h2->type = build_function_type (ret_type, args);
12256 return ((struct builtin_hash_struct *)(*found))->type;
12260 rs6000_common_init_builtins (void)
12262 const struct builtin_description *d;
12265 tree opaque_ftype_opaque = NULL_TREE;
12266 tree opaque_ftype_opaque_opaque = NULL_TREE;
12267 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12268 tree v2si_ftype_qi = NULL_TREE;
12269 tree v2si_ftype_v2si_qi = NULL_TREE;
12270 tree v2si_ftype_int_qi = NULL_TREE;
12272 if (!TARGET_PAIRED_FLOAT)
12274 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12275 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12278 /* Add the ternary operators. */
12280 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12283 int mask = d->mask;
12285 if ((mask != 0 && (mask & target_flags) == 0)
12286 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12289 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12290 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12291 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12292 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12294 if (! (type = opaque_ftype_opaque_opaque_opaque))
12295 type = opaque_ftype_opaque_opaque_opaque
12296 = build_function_type_list (opaque_V4SI_type_node,
12297 opaque_V4SI_type_node,
12298 opaque_V4SI_type_node,
12299 opaque_V4SI_type_node,
12304 enum insn_code icode = d->icode;
12305 if (d->name == 0 || icode == CODE_FOR_nothing)
12308 type = builtin_function_type (insn_data[icode].operand[0].mode,
12309 insn_data[icode].operand[1].mode,
12310 insn_data[icode].operand[2].mode,
12311 insn_data[icode].operand[3].mode,
12315 def_builtin (d->mask, d->name, type, d->code);
12318 /* Add the binary operators. */
12320 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12322 enum machine_mode mode0, mode1, mode2;
12324 int mask = d->mask;
12326 if ((mask != 0 && (mask & target_flags) == 0)
12327 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12330 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12331 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12332 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12333 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12335 if (! (type = opaque_ftype_opaque_opaque))
12336 type = opaque_ftype_opaque_opaque
12337 = build_function_type_list (opaque_V4SI_type_node,
12338 opaque_V4SI_type_node,
12339 opaque_V4SI_type_node,
12344 enum insn_code icode = d->icode;
12345 if (d->name == 0 || icode == CODE_FOR_nothing)
12348 mode0 = insn_data[icode].operand[0].mode;
12349 mode1 = insn_data[icode].operand[1].mode;
12350 mode2 = insn_data[icode].operand[2].mode;
12352 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12354 if (! (type = v2si_ftype_v2si_qi))
12355 type = v2si_ftype_v2si_qi
12356 = build_function_type_list (opaque_V2SI_type_node,
12357 opaque_V2SI_type_node,
12362 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12363 && mode2 == QImode)
12365 if (! (type = v2si_ftype_int_qi))
12366 type = v2si_ftype_int_qi
12367 = build_function_type_list (opaque_V2SI_type_node,
12374 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12378 def_builtin (d->mask, d->name, type, d->code);
12381 /* Add the simple unary operators. */
12382 d = (struct builtin_description *) bdesc_1arg;
12383 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12385 enum machine_mode mode0, mode1;
12387 int mask = d->mask;
12389 if ((mask != 0 && (mask & target_flags) == 0)
12390 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12393 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12394 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12395 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12396 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12398 if (! (type = opaque_ftype_opaque))
12399 type = opaque_ftype_opaque
12400 = build_function_type_list (opaque_V4SI_type_node,
12401 opaque_V4SI_type_node,
12406 enum insn_code icode = d->icode;
12407 if (d->name == 0 || icode == CODE_FOR_nothing)
12410 mode0 = insn_data[icode].operand[0].mode;
12411 mode1 = insn_data[icode].operand[1].mode;
12413 if (mode0 == V2SImode && mode1 == QImode)
12415 if (! (type = v2si_ftype_qi))
12416 type = v2si_ftype_qi
12417 = build_function_type_list (opaque_V2SI_type_node,
12423 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12427 def_builtin (d->mask, d->name, type, d->code);
12432 rs6000_init_libfuncs (void)
12434 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12435 && !TARGET_POWER2 && !TARGET_POWERPC)
12437 /* AIX library routines for float->int conversion. */
12438 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12439 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12440 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12441 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12444 if (!TARGET_IEEEQUAD)
12445 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12446 if (!TARGET_XL_COMPAT)
12448 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12449 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12450 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12451 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12453 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12455 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12456 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12457 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12458 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12459 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12460 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12461 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12463 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12464 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12465 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12466 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12467 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12468 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12469 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12470 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12473 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12474 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12478 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12479 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12480 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12481 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12485 /* 32-bit SVR4 quad floating point routines. */
12487 set_optab_libfunc (add_optab, TFmode, "_q_add");
12488 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12489 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12490 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12491 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12492 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12493 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12495 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12496 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12497 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12498 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12499 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12500 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12502 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12503 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12504 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12505 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12506 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12507 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12508 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12509 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12514 /* Expand a block clear operation, and return 1 if successful. Return 0
12515 if we should let the compiler generate normal code.
12517 operands[0] is the destination
12518 operands[1] is the length
12519 operands[3] is the alignment */
12522 expand_block_clear (rtx operands[])
12524 rtx orig_dest = operands[0];
12525 rtx bytes_rtx = operands[1];
12526 rtx align_rtx = operands[3];
12527 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12528 HOST_WIDE_INT align;
12529 HOST_WIDE_INT bytes;
12534 /* If this is not a fixed size move, just call memcpy */
12538 /* This must be a fixed size alignment */
12539 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12540 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12542 /* Anything to clear? */
12543 bytes = INTVAL (bytes_rtx);
12547 /* Use the builtin memset after a point, to avoid huge code bloat.
12548 When optimize_size, avoid any significant code bloat; calling
12549 memset is about 4 instructions, so allow for one instruction to
12550 load zero and three to do clearing. */
12551 if (TARGET_ALTIVEC && align >= 128)
12553 else if (TARGET_POWERPC64 && align >= 32)
12555 else if (TARGET_SPE && align >= 64)
12560 if (optimize_size && bytes > 3 * clear_step)
12562 if (! optimize_size && bytes > 8 * clear_step)
12565 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12567 enum machine_mode mode = BLKmode;
12570 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12575 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12580 else if (bytes >= 8 && TARGET_POWERPC64
12581 /* 64-bit loads and stores require word-aligned
12583 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12588 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12589 { /* move 4 bytes */
12593 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12594 { /* move 2 bytes */
12598 else /* move 1 byte at a time */
12604 dest = adjust_address (orig_dest, mode, offset);
12606 emit_move_insn (dest, CONST0_RTX (mode));
12613 /* Expand a block move operation, and return 1 if successful. Return 0
12614 if we should let the compiler generate normal code.
12616 operands[0] is the destination
12617 operands[1] is the source
12618 operands[2] is the length
12619 operands[3] is the alignment */
12621 #define MAX_MOVE_REG 4
12624 expand_block_move (rtx operands[])
12626 rtx orig_dest = operands[0];
12627 rtx orig_src = operands[1];
12628 rtx bytes_rtx = operands[2];
12629 rtx align_rtx = operands[3];
12630 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12635 rtx stores[MAX_MOVE_REG];
12638 /* If this is not a fixed size move, just call memcpy */
12642 /* This must be a fixed size alignment */
12643 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12644 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12646 /* Anything to move? */
12647 bytes = INTVAL (bytes_rtx);
12651 /* store_one_arg depends on expand_block_move to handle at least the size of
12652 reg_parm_stack_space. */
12653 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12656 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12659 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12660 rtx (*mov) (rtx, rtx);
12662 enum machine_mode mode = BLKmode;
12665 /* Altivec first, since it will be faster than a string move
12666 when it applies, and usually not significantly larger. */
12667 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12671 gen_func.mov = gen_movv4si;
12673 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12677 gen_func.mov = gen_movv2si;
12679 else if (TARGET_STRING
12680 && bytes > 24 /* move up to 32 bytes at a time */
12686 && ! fixed_regs[10]
12687 && ! fixed_regs[11]
12688 && ! fixed_regs[12])
12690 move_bytes = (bytes > 32) ? 32 : bytes;
12691 gen_func.movmemsi = gen_movmemsi_8reg;
12693 else if (TARGET_STRING
12694 && bytes > 16 /* move up to 24 bytes at a time */
12700 && ! fixed_regs[10])
12702 move_bytes = (bytes > 24) ? 24 : bytes;
12703 gen_func.movmemsi = gen_movmemsi_6reg;
12705 else if (TARGET_STRING
12706 && bytes > 8 /* move up to 16 bytes at a time */
12710 && ! fixed_regs[8])
12712 move_bytes = (bytes > 16) ? 16 : bytes;
12713 gen_func.movmemsi = gen_movmemsi_4reg;
12715 else if (bytes >= 8 && TARGET_POWERPC64
12716 /* 64-bit loads and stores require word-aligned
12718 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12722 gen_func.mov = gen_movdi;
12724 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12725 { /* move up to 8 bytes at a time */
12726 move_bytes = (bytes > 8) ? 8 : bytes;
12727 gen_func.movmemsi = gen_movmemsi_2reg;
12729 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12730 { /* move 4 bytes */
12733 gen_func.mov = gen_movsi;
12735 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12736 { /* move 2 bytes */
12739 gen_func.mov = gen_movhi;
12741 else if (TARGET_STRING && bytes > 1)
12742 { /* move up to 4 bytes at a time */
12743 move_bytes = (bytes > 4) ? 4 : bytes;
12744 gen_func.movmemsi = gen_movmemsi_1reg;
12746 else /* move 1 byte at a time */
12750 gen_func.mov = gen_movqi;
12753 src = adjust_address (orig_src, mode, offset);
12754 dest = adjust_address (orig_dest, mode, offset);
12756 if (mode != BLKmode)
12758 rtx tmp_reg = gen_reg_rtx (mode);
12760 emit_insn ((*gen_func.mov) (tmp_reg, src));
12761 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12764 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12767 for (i = 0; i < num_reg; i++)
12768 emit_insn (stores[i]);
12772 if (mode == BLKmode)
12774 /* Move the address into scratch registers. The movmemsi
12775 patterns require zero offset. */
12776 if (!REG_P (XEXP (src, 0)))
12778 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12779 src = replace_equiv_address (src, src_reg);
12781 set_mem_size (src, GEN_INT (move_bytes));
12783 if (!REG_P (XEXP (dest, 0)))
12785 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12786 dest = replace_equiv_address (dest, dest_reg);
12788 set_mem_size (dest, GEN_INT (move_bytes));
12790 emit_insn ((*gen_func.movmemsi) (dest, src,
12791 GEN_INT (move_bytes & 31),
12800 /* Return a string to perform a load_multiple operation.
12801 operands[0] is the vector.
12802 operands[1] is the source address.
12803 operands[2] is the first destination register. */
12806 rs6000_output_load_multiple (rtx operands[3])
12808 /* We have to handle the case where the pseudo used to contain the address
12809 is assigned to one of the output registers. */
12811 int words = XVECLEN (operands[0], 0);
12814 if (XVECLEN (operands[0], 0) == 1)
12815 return "{l|lwz} %2,0(%1)";
12817 for (i = 0; i < words; i++)
12818 if (refers_to_regno_p (REGNO (operands[2]) + i,
12819 REGNO (operands[2]) + i + 1, operands[1], 0))
12823 xop[0] = GEN_INT (4 * (words-1));
12824 xop[1] = operands[1];
12825 xop[2] = operands[2];
12826 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12831 xop[0] = GEN_INT (4 * (words-1));
12832 xop[1] = operands[1];
12833 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12834 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);
12839 for (j = 0; j < words; j++)
12842 xop[0] = GEN_INT (j * 4);
12843 xop[1] = operands[1];
12844 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12845 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12847 xop[0] = GEN_INT (i * 4);
12848 xop[1] = operands[1];
12849 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12854 return "{lsi|lswi} %2,%1,%N0";
12858 /* A validation routine: say whether CODE, a condition code, and MODE
12859 match. The other alternatives either don't make sense or should
12860 never be generated. */
12863 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12865 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12866 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12867 && GET_MODE_CLASS (mode) == MODE_CC);
12869 /* These don't make sense. */
12870 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12871 || mode != CCUNSmode);
12873 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12874 || mode == CCUNSmode);
12876 gcc_assert (mode == CCFPmode
12877 || (code != ORDERED && code != UNORDERED
12878 && code != UNEQ && code != LTGT
12879 && code != UNGT && code != UNLT
12880 && code != UNGE && code != UNLE));
12882 /* These should never be generated except for
12883 flag_finite_math_only. */
12884 gcc_assert (mode != CCFPmode
12885 || flag_finite_math_only
12886 || (code != LE && code != GE
12887 && code != UNEQ && code != LTGT
12888 && code != UNGT && code != UNLT));
12890 /* These are invalid; the information is not there. */
12891 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12895 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12896 mask required to convert the result of a rotate insn into a shift
12897 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12900 includes_lshift_p (rtx shiftop, rtx andop)
12902 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12904 shift_mask <<= INTVAL (shiftop);
12906 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12909 /* Similar, but for right shift. */
12912 includes_rshift_p (rtx shiftop, rtx andop)
12914 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12916 shift_mask >>= INTVAL (shiftop);
12918 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12921 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12922 to perform a left shift. It must have exactly SHIFTOP least
12923 significant 0's, then one or more 1's, then zero or more 0's. */
12926 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12928 if (GET_CODE (andop) == CONST_INT)
12930 HOST_WIDE_INT c, lsb, shift_mask;
12932 c = INTVAL (andop);
12933 if (c == 0 || c == ~0)
12937 shift_mask <<= INTVAL (shiftop);
12939 /* Find the least significant one bit. */
12942 /* It must coincide with the LSB of the shift mask. */
12943 if (-lsb != shift_mask)
12946 /* Invert to look for the next transition (if any). */
12949 /* Remove the low group of ones (originally low group of zeros). */
12952 /* Again find the lsb, and check we have all 1's above. */
12956 else if (GET_CODE (andop) == CONST_DOUBLE
12957 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12959 HOST_WIDE_INT low, high, lsb;
12960 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12962 low = CONST_DOUBLE_LOW (andop);
12963 if (HOST_BITS_PER_WIDE_INT < 64)
12964 high = CONST_DOUBLE_HIGH (andop);
12966 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12967 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12970 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12972 shift_mask_high = ~0;
12973 if (INTVAL (shiftop) > 32)
12974 shift_mask_high <<= INTVAL (shiftop) - 32;
12976 lsb = high & -high;
12978 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12984 lsb = high & -high;
12985 return high == -lsb;
12988 shift_mask_low = ~0;
12989 shift_mask_low <<= INTVAL (shiftop);
12993 if (-lsb != shift_mask_low)
12996 if (HOST_BITS_PER_WIDE_INT < 64)
13001 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13003 lsb = high & -high;
13004 return high == -lsb;
13008 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13014 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13015 to perform a left shift. It must have SHIFTOP or more least
13016 significant 0's, with the remainder of the word 1's. */
13019 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13021 if (GET_CODE (andop) == CONST_INT)
13023 HOST_WIDE_INT c, lsb, shift_mask;
13026 shift_mask <<= INTVAL (shiftop);
13027 c = INTVAL (andop);
13029 /* Find the least significant one bit. */
13032 /* It must be covered by the shift mask.
13033 This test also rejects c == 0. */
13034 if ((lsb & shift_mask) == 0)
13037 /* Check we have all 1's above the transition, and reject all 1's. */
13038 return c == -lsb && lsb != 1;
13040 else if (GET_CODE (andop) == CONST_DOUBLE
13041 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13043 HOST_WIDE_INT low, lsb, shift_mask_low;
13045 low = CONST_DOUBLE_LOW (andop);
13047 if (HOST_BITS_PER_WIDE_INT < 64)
13049 HOST_WIDE_INT high, shift_mask_high;
13051 high = CONST_DOUBLE_HIGH (andop);
13055 shift_mask_high = ~0;
13056 if (INTVAL (shiftop) > 32)
13057 shift_mask_high <<= INTVAL (shiftop) - 32;
13059 lsb = high & -high;
13061 if ((lsb & shift_mask_high) == 0)
13064 return high == -lsb;
13070 shift_mask_low = ~0;
13071 shift_mask_low <<= INTVAL (shiftop);
13075 if ((lsb & shift_mask_low) == 0)
13078 return low == -lsb && lsb != 1;
13084 /* Return 1 if operands will generate a valid arguments to rlwimi
13085 instruction for insert with right shift in 64-bit mode. The mask may
13086 not start on the first bit or stop on the last bit because wrap-around
13087 effects of instruction do not correspond to semantics of RTL insn. */
13090 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13092 if (INTVAL (startop) > 32
13093 && INTVAL (startop) < 64
13094 && INTVAL (sizeop) > 1
13095 && INTVAL (sizeop) + INTVAL (startop) < 64
13096 && INTVAL (shiftop) > 0
13097 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13098 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13104 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13105 for lfq and stfq insns iff the registers are hard registers. */
13108 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13110 /* We might have been passed a SUBREG. */
13111 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13114 /* We might have been passed non floating point registers. */
13115 if (!FP_REGNO_P (REGNO (reg1))
13116 || !FP_REGNO_P (REGNO (reg2)))
13119 return (REGNO (reg1) == REGNO (reg2) - 1);
13122 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13123 addr1 and addr2 must be in consecutive memory locations
13124 (addr2 == addr1 + 8). */
13127 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13130 unsigned int reg1, reg2;
13131 int offset1, offset2;
13133 /* The mems cannot be volatile. */
13134 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13137 addr1 = XEXP (mem1, 0);
13138 addr2 = XEXP (mem2, 0);
13140 /* Extract an offset (if used) from the first addr. */
13141 if (GET_CODE (addr1) == PLUS)
13143 /* If not a REG, return zero. */
13144 if (GET_CODE (XEXP (addr1, 0)) != REG)
13148 reg1 = REGNO (XEXP (addr1, 0));
13149 /* The offset must be constant! */
13150 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13152 offset1 = INTVAL (XEXP (addr1, 1));
13155 else if (GET_CODE (addr1) != REG)
13159 reg1 = REGNO (addr1);
13160 /* This was a simple (mem (reg)) expression. Offset is 0. */
13164 /* And now for the second addr. */
13165 if (GET_CODE (addr2) == PLUS)
13167 /* If not a REG, return zero. */
13168 if (GET_CODE (XEXP (addr2, 0)) != REG)
13172 reg2 = REGNO (XEXP (addr2, 0));
13173 /* The offset must be constant. */
13174 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13176 offset2 = INTVAL (XEXP (addr2, 1));
13179 else if (GET_CODE (addr2) != REG)
13183 reg2 = REGNO (addr2);
13184 /* This was a simple (mem (reg)) expression. Offset is 0. */
13188 /* Both of these must have the same base register. */
13192 /* The offset for the second addr must be 8 more than the first addr. */
13193 if (offset2 != offset1 + 8)
13196 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13203 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13205 static bool eliminated = false;
13208 if (mode != SDmode)
13209 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13212 rtx mem = cfun->machine->sdmode_stack_slot;
13213 gcc_assert (mem != NULL_RTX);
13217 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13218 cfun->machine->sdmode_stack_slot = mem;
13224 if (TARGET_DEBUG_ADDR)
13226 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13227 GET_MODE_NAME (mode));
13229 fprintf (stderr, "\tNULL_RTX\n");
13238 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13240 /* Don't walk into types. */
13241 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13243 *walk_subtrees = 0;
13247 switch (TREE_CODE (*tp))
13256 case ALIGN_INDIRECT_REF:
13257 case MISALIGNED_INDIRECT_REF:
13258 case VIEW_CONVERT_EXPR:
13259 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13269 enum reload_reg_type {
13271 VECTOR_REGISTER_TYPE,
13272 OTHER_REGISTER_TYPE
13275 static enum reload_reg_type
13276 rs6000_reload_register_type (enum reg_class rclass)
13282 return GPR_REGISTER_TYPE;
13287 return VECTOR_REGISTER_TYPE;
13290 return OTHER_REGISTER_TYPE;
13294 /* Inform reload about cases where moving X with a mode MODE to a register in
13295 RCLASS requires an extra scratch or immediate register. Return the class
13296 needed for the immediate register.
13298 For VSX and Altivec, we may need a register to convert sp+offset into
13301 static enum reg_class
13302 rs6000_secondary_reload (bool in_p,
13304 enum reg_class rclass,
13305 enum machine_mode mode,
13306 secondary_reload_info *sri)
13308 enum reg_class ret = ALL_REGS;
13309 enum insn_code icode;
13310 bool default_p = false;
13312 sri->icode = CODE_FOR_nothing;
13314 /* Convert vector loads and stores into gprs to use an additional base
13316 icode = rs6000_vector_reload[mode][in_p != false];
13317 if (icode != CODE_FOR_nothing)
13320 sri->icode = CODE_FOR_nothing;
13321 sri->extra_cost = 0;
13323 if (GET_CODE (x) == MEM)
13325 rtx addr = XEXP (x, 0);
13327 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13328 an extra register in that case, but it would need an extra
13329 register if the addressing is reg+reg or (reg+reg)&(-16). */
13330 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13332 if (!legitimate_indirect_address_p (addr, false)
13333 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13335 sri->icode = icode;
13336 /* account for splitting the loads, and converting the
13337 address from reg+reg to reg. */
13338 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13339 + ((GET_CODE (addr) == AND) ? 1 : 0));
13342 /* Loads to and stores from vector registers can only do reg+reg
13343 addressing. Altivec registers can also do (reg+reg)&(-16). */
13344 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13345 || rclass == FLOAT_REGS || rclass == NO_REGS)
13347 if (!VECTOR_MEM_ALTIVEC_P (mode)
13348 && GET_CODE (addr) == AND
13349 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13350 && INTVAL (XEXP (addr, 1)) == -16
13351 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13352 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13354 sri->icode = icode;
13355 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13358 else if (!legitimate_indirect_address_p (addr, false)
13359 && (rclass == NO_REGS
13360 || !legitimate_indexed_address_p (addr, false)))
13362 sri->icode = icode;
13363 sri->extra_cost = 1;
13366 icode = CODE_FOR_nothing;
13368 /* Any other loads, including to pseudo registers which haven't been
13369 assigned to a register yet, default to require a scratch
13373 sri->icode = icode;
13374 sri->extra_cost = 2;
13377 else if (REG_P (x))
13379 int regno = true_regnum (x);
13381 icode = CODE_FOR_nothing;
13382 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13386 enum reg_class xclass = REGNO_REG_CLASS (regno);
13387 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13388 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13390 /* If memory is needed, use default_secondary_reload to create the
13392 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13405 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13407 gcc_assert (ret != ALL_REGS);
13409 if (TARGET_DEBUG_ADDR)
13412 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13414 reg_class_names[ret],
13415 in_p ? "true" : "false",
13416 reg_class_names[rclass],
13417 GET_MODE_NAME (mode));
13420 fprintf (stderr, ", default secondary reload");
13422 if (sri->icode != CODE_FOR_nothing)
13423 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13424 insn_data[sri->icode].name, sri->extra_cost);
13426 fprintf (stderr, "\n");
13434 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13435 to SP+reg addressing. */
13438 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13440 int regno = true_regnum (reg);
13441 enum machine_mode mode = GET_MODE (reg);
13442 enum reg_class rclass;
13444 rtx and_op2 = NULL_RTX;
13447 rtx scratch_or_premodify = scratch;
13451 if (TARGET_DEBUG_ADDR)
13453 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13454 store_p ? "store" : "load");
13455 fprintf (stderr, "reg:\n");
13457 fprintf (stderr, "mem:\n");
13459 fprintf (stderr, "scratch:\n");
13460 debug_rtx (scratch);
13463 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13464 gcc_assert (GET_CODE (mem) == MEM);
13465 rclass = REGNO_REG_CLASS (regno);
13466 addr = XEXP (mem, 0);
13470 /* GPRs can handle reg + small constant, all other addresses need to use
13471 the scratch register. */
13474 if (GET_CODE (addr) == AND)
13476 and_op2 = XEXP (addr, 1);
13477 addr = XEXP (addr, 0);
13480 if (GET_CODE (addr) == PRE_MODIFY)
13482 scratch_or_premodify = XEXP (addr, 0);
13483 gcc_assert (REG_P (scratch_or_premodify));
13484 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13485 addr = XEXP (addr, 1);
13488 if (GET_CODE (addr) == PLUS
13489 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13490 || and_op2 != NULL_RTX))
13492 addr_op1 = XEXP (addr, 0);
13493 addr_op2 = XEXP (addr, 1);
13494 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13496 if (!REG_P (addr_op2)
13497 && (GET_CODE (addr_op2) != CONST_INT
13498 || !satisfies_constraint_I (addr_op2)))
13500 if (TARGET_DEBUG_ADDR)
13503 "\nMove plus addr to register %s, mode = %s: ",
13504 rs6000_reg_names[REGNO (scratch)],
13505 GET_MODE_NAME (mode));
13506 debug_rtx (addr_op2);
13508 rs6000_emit_move (scratch, addr_op2, Pmode);
13509 addr_op2 = scratch;
13512 emit_insn (gen_rtx_SET (VOIDmode,
13513 scratch_or_premodify,
13514 gen_rtx_PLUS (Pmode,
13518 addr = scratch_or_premodify;
13519 scratch_or_premodify = scratch;
13521 else if (!legitimate_indirect_address_p (addr, false)
13522 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13524 if (TARGET_DEBUG_ADDR)
13526 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13527 rs6000_reg_names[REGNO (scratch_or_premodify)],
13528 GET_MODE_NAME (mode));
13531 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13532 addr = scratch_or_premodify;
13533 scratch_or_premodify = scratch;
13537 /* Float/Altivec registers can only handle reg+reg addressing. Move
13538 other addresses into a scratch register. */
13543 /* With float regs, we need to handle the AND ourselves, since we can't
13544 use the Altivec instruction with an implicit AND -16. Allow scalar
13545 loads to float registers to use reg+offset even if VSX. */
13546 if (GET_CODE (addr) == AND
13547 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13548 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13549 || INTVAL (XEXP (addr, 1)) != -16
13550 || !VECTOR_MEM_ALTIVEC_P (mode)))
13552 and_op2 = XEXP (addr, 1);
13553 addr = XEXP (addr, 0);
13556 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13557 as the address later. */
13558 if (GET_CODE (addr) == PRE_MODIFY
13559 && (!VECTOR_MEM_VSX_P (mode)
13560 || and_op2 != NULL_RTX
13561 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13563 scratch_or_premodify = XEXP (addr, 0);
13564 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13566 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13567 addr = XEXP (addr, 1);
13570 if (legitimate_indirect_address_p (addr, false) /* reg */
13571 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13572 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13573 || (GET_CODE (addr) == AND /* Altivec memory */
13574 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13575 && INTVAL (XEXP (addr, 1)) == -16
13576 && VECTOR_MEM_ALTIVEC_P (mode))
13577 || (rclass == FLOAT_REGS /* legacy float mem */
13578 && GET_MODE_SIZE (mode) == 8
13579 && and_op2 == NULL_RTX
13580 && scratch_or_premodify == scratch
13581 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13584 else if (GET_CODE (addr) == PLUS)
13586 addr_op1 = XEXP (addr, 0);
13587 addr_op2 = XEXP (addr, 1);
13588 gcc_assert (REG_P (addr_op1));
13590 if (TARGET_DEBUG_ADDR)
13592 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13593 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13594 debug_rtx (addr_op2);
13596 rs6000_emit_move (scratch, addr_op2, Pmode);
13597 emit_insn (gen_rtx_SET (VOIDmode,
13598 scratch_or_premodify,
13599 gen_rtx_PLUS (Pmode,
13602 addr = scratch_or_premodify;
13603 scratch_or_premodify = scratch;
13606 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13607 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13609 if (TARGET_DEBUG_ADDR)
13611 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13612 rs6000_reg_names[REGNO (scratch_or_premodify)],
13613 GET_MODE_NAME (mode));
13617 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13618 addr = scratch_or_premodify;
13619 scratch_or_premodify = scratch;
13623 gcc_unreachable ();
13628 gcc_unreachable ();
13631 /* If the original address involved a pre-modify that we couldn't use the VSX
13632 memory instruction with update, and we haven't taken care of already,
13633 store the address in the pre-modify register and use that as the
13635 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13637 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13638 addr = scratch_or_premodify;
13641 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13642 memory instruction, recreate the AND now, including the clobber which is
13643 generated by the general ANDSI3/ANDDI3 patterns for the
13644 andi. instruction. */
13645 if (and_op2 != NULL_RTX)
13647 if (! legitimate_indirect_address_p (addr, false))
13649 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13653 if (TARGET_DEBUG_ADDR)
13655 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13656 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13657 debug_rtx (and_op2);
13660 and_rtx = gen_rtx_SET (VOIDmode,
13662 gen_rtx_AND (Pmode,
13666 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13667 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13668 gen_rtvec (2, and_rtx, cc_clobber)));
13672 /* Adjust the address if it changed. */
13673 if (addr != XEXP (mem, 0))
13675 mem = change_address (mem, mode, addr);
13676 if (TARGET_DEBUG_ADDR)
13677 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13680 /* Now create the move. */
13682 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13684 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13689 /* Target hook to return the cover classes for Integrated Register Allocator.
13690 Cover classes is a set of non-intersected register classes covering all hard
13691 registers used for register allocation purpose. Any move between two
13692 registers of a cover class should be cheaper than load or store of the
13693 registers. The value is array of register classes with LIM_REG_CLASSES used
13696 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13697 account for the Altivec and Floating registers being subsets of the VSX
13698 register set under VSX, but distinct register sets on pre-VSX machines. */
13700 static const enum reg_class *
13701 rs6000_ira_cover_classes (void)
13703 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13704 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13706 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13709 /* Allocate a 64-bit stack slot to be used for copying SDmode
13710 values through if this function has any SDmode references. */
13713 rs6000_alloc_sdmode_stack_slot (void)
13717 gimple_stmt_iterator gsi;
13719 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13722 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13724 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13727 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13728 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13734 /* Check for any SDmode parameters of the function. */
13735 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13737 if (TREE_TYPE (t) == error_mark_node)
13740 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13741 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13743 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13744 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13752 rs6000_instantiate_decls (void)
13754 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13755 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13758 /* Given an rtx X being reloaded into a reg required to be
13759 in class CLASS, return the class of reg to actually use.
13760 In general this is just CLASS; but on some machines
13761 in some cases it is preferable to use a more restrictive class.
13763 On the RS/6000, we have to return NO_REGS when we want to reload a
13764 floating-point CONST_DOUBLE to force it to be copied to memory.
13766 We also don't want to reload integer values into floating-point
13767 registers if we can at all help it. In fact, this can
13768 cause reload to die, if it tries to generate a reload of CTR
13769 into a FP register and discovers it doesn't have the memory location
13772 ??? Would it be a good idea to have reload do the converse, that is
13773 try to reload floating modes into FP registers if possible?
13776 static enum reg_class
13777 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13779 enum machine_mode mode = GET_MODE (x);
13781 if (VECTOR_UNIT_VSX_P (mode)
13782 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13785 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13786 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13787 && easy_vector_constant (x, mode))
13788 return ALTIVEC_REGS;
13790 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13793 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13794 return GENERAL_REGS;
13796 /* For VSX, prefer the traditional registers for DF if the address is of the
13797 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13798 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13800 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13802 if (mode == DFmode && GET_CODE (x) == MEM)
13804 rtx addr = XEXP (x, 0);
13806 if (legitimate_indirect_address_p (addr, false)) /* reg */
13809 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13812 if (GET_CODE (addr) == PRE_MODIFY
13813 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13819 if (VECTOR_UNIT_ALTIVEC_P (mode))
13820 return ALTIVEC_REGS;
13828 /* Debug version of rs6000_preferred_reload_class. */
13829 static enum reg_class
13830 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13832 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13835 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13837 reg_class_names[ret], reg_class_names[rclass],
13838 GET_MODE_NAME (GET_MODE (x)));
13844 /* If we are copying between FP or AltiVec registers and anything else, we need
13845 a memory location. The exception is when we are targeting ppc64 and the
13846 move to/from fpr to gpr instructions are available. Also, under VSX, you
13847 can copy vector registers from the FP register set to the Altivec register
13848 set and vice versa. */
13851 rs6000_secondary_memory_needed (enum reg_class class1,
13852 enum reg_class class2,
13853 enum machine_mode mode)
13855 if (class1 == class2)
13858 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13859 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13860 between these classes. But we need memory for other things that can go in
13861 FLOAT_REGS like SFmode. */
13863 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13864 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13865 || class1 == FLOAT_REGS))
13866 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13867 && class2 != FLOAT_REGS);
13869 if (class1 == VSX_REGS || class2 == VSX_REGS)
13872 if (class1 == FLOAT_REGS
13873 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13874 || ((mode != DFmode)
13875 && (mode != DDmode)
13876 && (mode != DImode))))
13879 if (class2 == FLOAT_REGS
13880 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13881 || ((mode != DFmode)
13882 && (mode != DDmode)
13883 && (mode != DImode))))
13886 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13892 /* Debug version of rs6000_secondary_memory_needed. */
13894 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13895 enum reg_class class2,
13896 enum machine_mode mode)
13898 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13901 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13902 "class2 = %s, mode = %s\n",
13903 ret ? "true" : "false", reg_class_names[class1],
13904 reg_class_names[class2], GET_MODE_NAME (mode));
13909 /* Return the register class of a scratch register needed to copy IN into
13910 or out of a register in RCLASS in MODE. If it can be done directly,
13911 NO_REGS is returned. */
13913 static enum reg_class
13914 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13919 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13921 && MACHOPIC_INDIRECT
13925 /* We cannot copy a symbolic operand directly into anything
13926 other than BASE_REGS for TARGET_ELF. So indicate that a
13927 register from BASE_REGS is needed as an intermediate
13930 On Darwin, pic addresses require a load from memory, which
13931 needs a base register. */
13932 if (rclass != BASE_REGS
13933 && (GET_CODE (in) == SYMBOL_REF
13934 || GET_CODE (in) == HIGH
13935 || GET_CODE (in) == LABEL_REF
13936 || GET_CODE (in) == CONST))
13940 if (GET_CODE (in) == REG)
13942 regno = REGNO (in);
13943 if (regno >= FIRST_PSEUDO_REGISTER)
13945 regno = true_regnum (in);
13946 if (regno >= FIRST_PSEUDO_REGISTER)
13950 else if (GET_CODE (in) == SUBREG)
13952 regno = true_regnum (in);
13953 if (regno >= FIRST_PSEUDO_REGISTER)
13959 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13961 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13962 || (regno >= 0 && INT_REGNO_P (regno)))
13965 /* Constants, memory, and FP registers can go into FP registers. */
13966 if ((regno == -1 || FP_REGNO_P (regno))
13967 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13968 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13970 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13973 && (regno == -1 || VSX_REGNO_P (regno))
13974 && VSX_REG_CLASS_P (rclass))
13977 /* Memory, and AltiVec registers can go into AltiVec registers. */
13978 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13979 && rclass == ALTIVEC_REGS)
13982 /* We can copy among the CR registers. */
13983 if ((rclass == CR_REGS || rclass == CR0_REGS)
13984 && regno >= 0 && CR_REGNO_P (regno))
13987 /* Otherwise, we need GENERAL_REGS. */
13988 return GENERAL_REGS;
13991 /* Debug version of rs6000_secondary_reload_class. */
13992 static enum reg_class
13993 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13994 enum machine_mode mode, rtx in)
13996 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13998 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13999 "mode = %s, input rtx:\n",
14000 reg_class_names[ret], reg_class_names[rclass],
14001 GET_MODE_NAME (mode));
14007 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14010 rs6000_cannot_change_mode_class (enum machine_mode from,
14011 enum machine_mode to,
14012 enum reg_class rclass)
14014 unsigned from_size = GET_MODE_SIZE (from);
14015 unsigned to_size = GET_MODE_SIZE (to);
14017 if (from_size != to_size)
14019 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14020 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14021 && reg_classes_intersect_p (xclass, rclass));
14024 if (TARGET_E500_DOUBLE
14025 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14026 || (((to) == TFmode) + ((from) == TFmode)) == 1
14027 || (((to) == DDmode) + ((from) == DDmode)) == 1
14028 || (((to) == TDmode) + ((from) == TDmode)) == 1
14029 || (((to) == DImode) + ((from) == DImode)) == 1))
14032 /* Since the VSX register set includes traditional floating point registers
14033 and altivec registers, just check for the size being different instead of
14034 trying to check whether the modes are vector modes. Otherwise it won't
14035 allow say DF and DI to change classes. */
14036 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14037 return (from_size != 8 && from_size != 16);
14039 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14040 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14043 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14044 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14050 /* Debug version of rs6000_cannot_change_mode_class. */
14052 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14053 enum machine_mode to,
14054 enum reg_class rclass)
14056 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14059 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14060 "to = %s, rclass = %s\n",
14061 ret ? "true" : "false",
14062 GET_MODE_NAME (from), GET_MODE_NAME (to),
14063 reg_class_names[rclass]);
14068 /* Given a comparison operation, return the bit number in CCR to test. We
14069 know this is a valid comparison.
14071 SCC_P is 1 if this is for an scc. That means that %D will have been
14072 used instead of %C, so the bits will be in different places.
14074 Return -1 if OP isn't a valid comparison for some reason. */
14077 ccr_bit (rtx op, int scc_p)
14079 enum rtx_code code = GET_CODE (op);
14080 enum machine_mode cc_mode;
14085 if (!COMPARISON_P (op))
14088 reg = XEXP (op, 0);
14090 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14092 cc_mode = GET_MODE (reg);
14093 cc_regnum = REGNO (reg);
14094 base_bit = 4 * (cc_regnum - CR0_REGNO);
14096 validate_condition_mode (code, cc_mode);
14098 /* When generating a sCOND operation, only positive conditions are
14101 || code == EQ || code == GT || code == LT || code == UNORDERED
14102 || code == GTU || code == LTU);
14107 return scc_p ? base_bit + 3 : base_bit + 2;
14109 return base_bit + 2;
14110 case GT: case GTU: case UNLE:
14111 return base_bit + 1;
14112 case LT: case LTU: case UNGE:
14114 case ORDERED: case UNORDERED:
14115 return base_bit + 3;
14118 /* If scc, we will have done a cror to put the bit in the
14119 unordered position. So test that bit. For integer, this is ! LT
14120 unless this is an scc insn. */
14121 return scc_p ? base_bit + 3 : base_bit;
14124 return scc_p ? base_bit + 3 : base_bit + 1;
14127 gcc_unreachable ();
14131 /* Return the GOT register. */
14134 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14136 /* The second flow pass currently (June 1999) can't update
14137 regs_ever_live without disturbing other parts of the compiler, so
14138 update it here to make the prolog/epilogue code happy. */
14139 if (!can_create_pseudo_p ()
14140 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14141 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14143 crtl->uses_pic_offset_table = 1;
14145 return pic_offset_table_rtx;
14148 /* Function to init struct machine_function.
14149 This will be called, via a pointer variable,
14150 from push_function_context. */
14152 static struct machine_function *
14153 rs6000_init_machine_status (void)
14155 return GGC_CNEW (machine_function);
14158 /* These macros test for integers and extract the low-order bits. */
14160 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14161 && GET_MODE (X) == VOIDmode)
14163 #define INT_LOWPART(X) \
14164 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14167 extract_MB (rtx op)
14170 unsigned long val = INT_LOWPART (op);
14172 /* If the high bit is zero, the value is the first 1 bit we find
14174 if ((val & 0x80000000) == 0)
14176 gcc_assert (val & 0xffffffff);
14179 while (((val <<= 1) & 0x80000000) == 0)
14184 /* If the high bit is set and the low bit is not, or the mask is all
14185 1's, the value is zero. */
14186 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14189 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14192 while (((val >>= 1) & 1) != 0)
14199 extract_ME (rtx op)
14202 unsigned long val = INT_LOWPART (op);
14204 /* If the low bit is zero, the value is the first 1 bit we find from
14206 if ((val & 1) == 0)
14208 gcc_assert (val & 0xffffffff);
14211 while (((val >>= 1) & 1) == 0)
14217 /* If the low bit is set and the high bit is not, or the mask is all
14218 1's, the value is 31. */
14219 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14222 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14225 while (((val <<= 1) & 0x80000000) != 0)
14231 /* Locate some local-dynamic symbol still in use by this function
14232 so that we can print its name in some tls_ld pattern. */
14234 static const char *
14235 rs6000_get_some_local_dynamic_name (void)
14239 if (cfun->machine->some_ld_name)
14240 return cfun->machine->some_ld_name;
14242 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14244 && for_each_rtx (&PATTERN (insn),
14245 rs6000_get_some_local_dynamic_name_1, 0))
14246 return cfun->machine->some_ld_name;
14248 gcc_unreachable ();
14251 /* Helper function for rs6000_get_some_local_dynamic_name. */
14254 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14258 if (GET_CODE (x) == SYMBOL_REF)
14260 const char *str = XSTR (x, 0);
14261 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14263 cfun->machine->some_ld_name = str;
14271 /* Write out a function code label. */
14274 rs6000_output_function_entry (FILE *file, const char *fname)
14276 if (fname[0] != '.')
14278 switch (DEFAULT_ABI)
14281 gcc_unreachable ();
14287 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14296 RS6000_OUTPUT_BASENAME (file, fname);
14298 assemble_name (file, fname);
14301 /* Print an operand. Recognize special options, documented below. */
14304 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14305 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14307 #define SMALL_DATA_RELOC "sda21"
14308 #define SMALL_DATA_REG 0
14312 print_operand (FILE *file, rtx x, int code)
14316 unsigned HOST_WIDE_INT uval;
14321 /* Write out an instruction after the call which may be replaced
14322 with glue code by the loader. This depends on the AIX version. */
14323 asm_fprintf (file, RS6000_CALL_GLUE);
14326 /* %a is output_address. */
14329 /* If X is a constant integer whose low-order 5 bits are zero,
14330 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14331 in the AIX assembler where "sri" with a zero shift count
14332 writes a trash instruction. */
14333 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14340 /* If constant, low-order 16 bits of constant, unsigned.
14341 Otherwise, write normally. */
14343 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14345 print_operand (file, x, 0);
14349 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14350 for 64-bit mask direction. */
14351 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14354 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14358 /* X is a CR register. Print the number of the GT bit of the CR. */
14359 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14360 output_operand_lossage ("invalid %%c value");
14362 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14366 /* Like 'J' but get to the GT bit only. */
14367 gcc_assert (GET_CODE (x) == REG);
14369 /* Bit 1 is GT bit. */
14370 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14372 /* Add one for shift count in rlinm for scc. */
14373 fprintf (file, "%d", i + 1);
14377 /* X is a CR register. Print the number of the EQ bit of the CR */
14378 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14379 output_operand_lossage ("invalid %%E value");
14381 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14385 /* X is a CR register. Print the shift count needed to move it
14386 to the high-order four bits. */
14387 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14388 output_operand_lossage ("invalid %%f value");
14390 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14394 /* Similar, but print the count for the rotate in the opposite
14396 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14397 output_operand_lossage ("invalid %%F value");
14399 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14403 /* X is a constant integer. If it is negative, print "m",
14404 otherwise print "z". This is to make an aze or ame insn. */
14405 if (GET_CODE (x) != CONST_INT)
14406 output_operand_lossage ("invalid %%G value");
14407 else if (INTVAL (x) >= 0)
14414 /* If constant, output low-order five bits. Otherwise, write
14417 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14419 print_operand (file, x, 0);
14423 /* If constant, output low-order six bits. Otherwise, write
14426 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14428 print_operand (file, x, 0);
14432 /* Print `i' if this is a constant, else nothing. */
14438 /* Write the bit number in CCR for jump. */
14439 i = ccr_bit (x, 0);
14441 output_operand_lossage ("invalid %%j code");
14443 fprintf (file, "%d", i);
14447 /* Similar, but add one for shift count in rlinm for scc and pass
14448 scc flag to `ccr_bit'. */
14449 i = ccr_bit (x, 1);
14451 output_operand_lossage ("invalid %%J code");
14453 /* If we want bit 31, write a shift count of zero, not 32. */
14454 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14458 /* X must be a constant. Write the 1's complement of the
14461 output_operand_lossage ("invalid %%k value");
14463 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14467 /* X must be a symbolic constant on ELF. Write an
14468 expression suitable for an 'addi' that adds in the low 16
14469 bits of the MEM. */
14470 if (GET_CODE (x) != CONST)
14472 print_operand_address (file, x);
14473 fputs ("@l", file);
14477 if (GET_CODE (XEXP (x, 0)) != PLUS
14478 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14479 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14480 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14481 output_operand_lossage ("invalid %%K value");
14482 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14483 fputs ("@l", file);
14484 /* For GNU as, there must be a non-alphanumeric character
14485 between 'l' and the number. The '-' is added by
14486 print_operand() already. */
14487 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14489 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14493 /* %l is output_asm_label. */
14496 /* Write second word of DImode or DFmode reference. Works on register
14497 or non-indexed memory only. */
14498 if (GET_CODE (x) == REG)
14499 fputs (reg_names[REGNO (x) + 1], file);
14500 else if (GET_CODE (x) == MEM)
14502 /* Handle possible auto-increment. Since it is pre-increment and
14503 we have already done it, we can just use an offset of word. */
14504 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14505 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14506 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14508 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14509 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14512 output_address (XEXP (adjust_address_nv (x, SImode,
14516 if (small_data_operand (x, GET_MODE (x)))
14517 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14518 reg_names[SMALL_DATA_REG]);
14523 /* MB value for a mask operand. */
14524 if (! mask_operand (x, SImode))
14525 output_operand_lossage ("invalid %%m value");
14527 fprintf (file, "%d", extract_MB (x));
14531 /* ME value for a mask operand. */
14532 if (! mask_operand (x, SImode))
14533 output_operand_lossage ("invalid %%M value");
14535 fprintf (file, "%d", extract_ME (x));
14538 /* %n outputs the negative of its operand. */
14541 /* Write the number of elements in the vector times 4. */
14542 if (GET_CODE (x) != PARALLEL)
14543 output_operand_lossage ("invalid %%N value");
14545 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14549 /* Similar, but subtract 1 first. */
14550 if (GET_CODE (x) != PARALLEL)
14551 output_operand_lossage ("invalid %%O value");
14553 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14557 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14559 || INT_LOWPART (x) < 0
14560 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14561 output_operand_lossage ("invalid %%p value");
14563 fprintf (file, "%d", i);
14567 /* The operand must be an indirect memory reference. The result
14568 is the register name. */
14569 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14570 || REGNO (XEXP (x, 0)) >= 32)
14571 output_operand_lossage ("invalid %%P value");
14573 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14577 /* This outputs the logical code corresponding to a boolean
14578 expression. The expression may have one or both operands
14579 negated (if one, only the first one). For condition register
14580 logical operations, it will also treat the negated
14581 CR codes as NOTs, but not handle NOTs of them. */
14583 const char *const *t = 0;
14585 enum rtx_code code = GET_CODE (x);
14586 static const char * const tbl[3][3] = {
14587 { "and", "andc", "nor" },
14588 { "or", "orc", "nand" },
14589 { "xor", "eqv", "xor" } };
14593 else if (code == IOR)
14595 else if (code == XOR)
14598 output_operand_lossage ("invalid %%q value");
14600 if (GET_CODE (XEXP (x, 0)) != NOT)
14604 if (GET_CODE (XEXP (x, 1)) == NOT)
14622 /* X is a CR register. Print the mask for `mtcrf'. */
14623 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14624 output_operand_lossage ("invalid %%R value");
14626 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14630 /* Low 5 bits of 32 - value */
14632 output_operand_lossage ("invalid %%s value");
14634 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14638 /* PowerPC64 mask position. All 0's is excluded.
14639 CONST_INT 32-bit mask is considered sign-extended so any
14640 transition must occur within the CONST_INT, not on the boundary. */
14641 if (! mask64_operand (x, DImode))
14642 output_operand_lossage ("invalid %%S value");
14644 uval = INT_LOWPART (x);
14646 if (uval & 1) /* Clear Left */
14648 #if HOST_BITS_PER_WIDE_INT > 64
14649 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14653 else /* Clear Right */
14656 #if HOST_BITS_PER_WIDE_INT > 64
14657 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14663 gcc_assert (i >= 0);
14664 fprintf (file, "%d", i);
14668 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14669 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14671 /* Bit 3 is OV bit. */
14672 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14674 /* If we want bit 31, write a shift count of zero, not 32. */
14675 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14679 /* Print the symbolic name of a branch target register. */
14680 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14681 && REGNO (x) != CTR_REGNO))
14682 output_operand_lossage ("invalid %%T value");
14683 else if (REGNO (x) == LR_REGNO)
14684 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14686 fputs ("ctr", file);
14690 /* High-order 16 bits of constant for use in unsigned operand. */
14692 output_operand_lossage ("invalid %%u value");
14694 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14695 (INT_LOWPART (x) >> 16) & 0xffff);
14699 /* High-order 16 bits of constant for use in signed operand. */
14701 output_operand_lossage ("invalid %%v value");
14703 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14704 (INT_LOWPART (x) >> 16) & 0xffff);
14708 /* Print `u' if this has an auto-increment or auto-decrement. */
14709 if (GET_CODE (x) == MEM
14710 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14711 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14712 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14717 /* Print the trap code for this operand. */
14718 switch (GET_CODE (x))
14721 fputs ("eq", file); /* 4 */
14724 fputs ("ne", file); /* 24 */
14727 fputs ("lt", file); /* 16 */
14730 fputs ("le", file); /* 20 */
14733 fputs ("gt", file); /* 8 */
14736 fputs ("ge", file); /* 12 */
14739 fputs ("llt", file); /* 2 */
14742 fputs ("lle", file); /* 6 */
14745 fputs ("lgt", file); /* 1 */
14748 fputs ("lge", file); /* 5 */
14751 gcc_unreachable ();
14756 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14759 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14760 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14762 print_operand (file, x, 0);
14766 /* MB value for a PowerPC64 rldic operand. */
14767 val = (GET_CODE (x) == CONST_INT
14768 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14773 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14774 if ((val <<= 1) < 0)
14777 #if HOST_BITS_PER_WIDE_INT == 32
14778 if (GET_CODE (x) == CONST_INT && i >= 0)
14779 i += 32; /* zero-extend high-part was all 0's */
14780 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14782 val = CONST_DOUBLE_LOW (x);
14788 for ( ; i < 64; i++)
14789 if ((val <<= 1) < 0)
14794 fprintf (file, "%d", i + 1);
14798 /* X is a FPR or Altivec register used in a VSX context. */
14799 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14800 output_operand_lossage ("invalid %%x value");
14803 int reg = REGNO (x);
14804 int vsx_reg = (FP_REGNO_P (reg)
14806 : reg - FIRST_ALTIVEC_REGNO + 32);
14808 #ifdef TARGET_REGNAMES
14809 if (TARGET_REGNAMES)
14810 fprintf (file, "%%vs%d", vsx_reg);
14813 fprintf (file, "%d", vsx_reg);
14818 if (GET_CODE (x) == MEM
14819 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14820 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14821 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14826 /* Like 'L', for third word of TImode */
14827 if (GET_CODE (x) == REG)
14828 fputs (reg_names[REGNO (x) + 2], file);
14829 else if (GET_CODE (x) == MEM)
14831 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14832 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14833 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14834 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14835 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14837 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14838 if (small_data_operand (x, GET_MODE (x)))
14839 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14840 reg_names[SMALL_DATA_REG]);
14845 /* X is a SYMBOL_REF. Write out the name preceded by a
14846 period and without any trailing data in brackets. Used for function
14847 names. If we are configured for System V (or the embedded ABI) on
14848 the PowerPC, do not emit the period, since those systems do not use
14849 TOCs and the like. */
14850 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14852 /* Mark the decl as referenced so that cgraph will output the
14854 if (SYMBOL_REF_DECL (x))
14855 mark_decl_referenced (SYMBOL_REF_DECL (x));
14857 /* For macho, check to see if we need a stub. */
14860 const char *name = XSTR (x, 0);
14862 if (MACHOPIC_INDIRECT
14863 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14864 name = machopic_indirection_name (x, /*stub_p=*/true);
14866 assemble_name (file, name);
14868 else if (!DOT_SYMBOLS)
14869 assemble_name (file, XSTR (x, 0));
14871 rs6000_output_function_entry (file, XSTR (x, 0));
14875 /* Like 'L', for last word of TImode. */
14876 if (GET_CODE (x) == REG)
14877 fputs (reg_names[REGNO (x) + 3], file);
14878 else if (GET_CODE (x) == MEM)
14880 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14881 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14882 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14883 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14884 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14886 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14887 if (small_data_operand (x, GET_MODE (x)))
14888 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14889 reg_names[SMALL_DATA_REG]);
14893 /* Print AltiVec or SPE memory operand. */
14898 gcc_assert (GET_CODE (x) == MEM);
14902 /* Ugly hack because %y is overloaded. */
14903 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14904 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14905 || GET_MODE (x) == TFmode
14906 || GET_MODE (x) == TImode))
14908 /* Handle [reg]. */
14909 if (GET_CODE (tmp) == REG)
14911 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14914 /* Handle [reg+UIMM]. */
14915 else if (GET_CODE (tmp) == PLUS &&
14916 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14920 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14922 x = INTVAL (XEXP (tmp, 1));
14923 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14927 /* Fall through. Must be [reg+reg]. */
14929 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14930 && GET_CODE (tmp) == AND
14931 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14932 && INTVAL (XEXP (tmp, 1)) == -16)
14933 tmp = XEXP (tmp, 0);
14934 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14935 && GET_CODE (tmp) == PRE_MODIFY)
14936 tmp = XEXP (tmp, 1);
14937 if (GET_CODE (tmp) == REG)
14938 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14941 if (!GET_CODE (tmp) == PLUS
14942 || !REG_P (XEXP (tmp, 0))
14943 || !REG_P (XEXP (tmp, 1)))
14945 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14949 if (REGNO (XEXP (tmp, 0)) == 0)
14950 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14951 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14953 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14954 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14960 if (GET_CODE (x) == REG)
14961 fprintf (file, "%s", reg_names[REGNO (x)]);
14962 else if (GET_CODE (x) == MEM)
14964 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14965 know the width from the mode. */
14966 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14967 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14968 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14969 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14970 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14971 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14972 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14973 output_address (XEXP (XEXP (x, 0), 1));
14975 output_address (XEXP (x, 0));
14978 output_addr_const (file, x);
14982 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14986 output_operand_lossage ("invalid %%xn code");
14990 /* Print the address of an operand. */
14993 print_operand_address (FILE *file, rtx x)
14995 if (GET_CODE (x) == REG)
14996 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14997 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14998 || GET_CODE (x) == LABEL_REF)
15000 output_addr_const (file, x);
15001 if (small_data_operand (x, GET_MODE (x)))
15002 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15003 reg_names[SMALL_DATA_REG]);
15005 gcc_assert (!TARGET_TOC);
15007 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15009 gcc_assert (REG_P (XEXP (x, 0)));
15010 if (REGNO (XEXP (x, 0)) == 0)
15011 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15012 reg_names[ REGNO (XEXP (x, 0)) ]);
15014 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15015 reg_names[ REGNO (XEXP (x, 1)) ]);
15017 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15018 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15019 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15021 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15022 && CONSTANT_P (XEXP (x, 1)))
15024 output_addr_const (file, XEXP (x, 1));
15025 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15029 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15030 && CONSTANT_P (XEXP (x, 1)))
15032 fprintf (file, "lo16(");
15033 output_addr_const (file, XEXP (x, 1));
15034 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15037 else if (legitimate_constant_pool_address_p (x))
15039 output_addr_const (file, XEXP (x, 1));
15040 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15043 gcc_unreachable ();
15046 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15049 rs6000_output_addr_const_extra (FILE *file, rtx x)
15051 if (GET_CODE (x) == UNSPEC)
15052 switch (XINT (x, 1))
15054 case UNSPEC_TOCREL:
15055 x = XVECEXP (x, 0, 0);
15056 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15057 output_addr_const (file, x);
15058 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15061 assemble_name (file, toc_label_name);
15063 else if (TARGET_ELF)
15064 fputs ("@toc", file);
15068 case UNSPEC_MACHOPIC_OFFSET:
15069 output_addr_const (file, XVECEXP (x, 0, 0));
15071 machopic_output_function_base_name (file);
15078 /* Target hook for assembling integer objects. The PowerPC version has
15079 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15080 is defined. It also needs to handle DI-mode objects on 64-bit
15084 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15086 #ifdef RELOCATABLE_NEEDS_FIXUP
15087 /* Special handling for SI values. */
15088 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15090 static int recurse = 0;
15092 /* For -mrelocatable, we mark all addresses that need to be fixed up
15093 in the .fixup section. */
15094 if (TARGET_RELOCATABLE
15095 && in_section != toc_section
15096 && in_section != text_section
15097 && !unlikely_text_section_p (in_section)
15099 && GET_CODE (x) != CONST_INT
15100 && GET_CODE (x) != CONST_DOUBLE
15106 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15108 ASM_OUTPUT_LABEL (asm_out_file, buf);
15109 fprintf (asm_out_file, "\t.long\t(");
15110 output_addr_const (asm_out_file, x);
15111 fprintf (asm_out_file, ")@fixup\n");
15112 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15113 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15114 fprintf (asm_out_file, "\t.long\t");
15115 assemble_name (asm_out_file, buf);
15116 fprintf (asm_out_file, "\n\t.previous\n");
15120 /* Remove initial .'s to turn a -mcall-aixdesc function
15121 address into the address of the descriptor, not the function
15123 else if (GET_CODE (x) == SYMBOL_REF
15124 && XSTR (x, 0)[0] == '.'
15125 && DEFAULT_ABI == ABI_AIX)
15127 const char *name = XSTR (x, 0);
15128 while (*name == '.')
15131 fprintf (asm_out_file, "\t.long\t%s\n", name);
15135 #endif /* RELOCATABLE_NEEDS_FIXUP */
15136 return default_assemble_integer (x, size, aligned_p);
15139 #ifdef HAVE_GAS_HIDDEN
15140 /* Emit an assembler directive to set symbol visibility for DECL to
15141 VISIBILITY_TYPE. */
15144 rs6000_assemble_visibility (tree decl, int vis)
15146 /* Functions need to have their entry point symbol visibility set as
15147 well as their descriptor symbol visibility. */
15148 if (DEFAULT_ABI == ABI_AIX
15150 && TREE_CODE (decl) == FUNCTION_DECL)
15152 static const char * const visibility_types[] = {
15153 NULL, "internal", "hidden", "protected"
15156 const char *name, *type;
15158 name = ((* targetm.strip_name_encoding)
15159 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15160 type = visibility_types[vis];
15162 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15163 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15166 default_assemble_visibility (decl, vis);
15171 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15173 /* Reversal of FP compares takes care -- an ordered compare
15174 becomes an unordered compare and vice versa. */
15175 if (mode == CCFPmode
15176 && (!flag_finite_math_only
15177 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15178 || code == UNEQ || code == LTGT))
15179 return reverse_condition_maybe_unordered (code);
15181 return reverse_condition (code);
15184 /* Generate a compare for CODE. Return a brand-new rtx that
15185 represents the result of the compare. */
15188 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15190 enum machine_mode comp_mode;
15191 rtx compare_result;
15192 enum rtx_code code = GET_CODE (cmp);
15193 rtx op0 = XEXP (cmp, 0);
15194 rtx op1 = XEXP (cmp, 1);
15196 if (FLOAT_MODE_P (mode))
15197 comp_mode = CCFPmode;
15198 else if (code == GTU || code == LTU
15199 || code == GEU || code == LEU)
15200 comp_mode = CCUNSmode;
15201 else if ((code == EQ || code == NE)
15202 && GET_CODE (op0) == SUBREG
15203 && GET_CODE (op1) == SUBREG
15204 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15205 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15206 /* These are unsigned values, perhaps there will be a later
15207 ordering compare that can be shared with this one.
15208 Unfortunately we cannot detect the signedness of the operands
15209 for non-subregs. */
15210 comp_mode = CCUNSmode;
15212 comp_mode = CCmode;
15214 /* First, the compare. */
15215 compare_result = gen_reg_rtx (comp_mode);
15217 /* E500 FP compare instructions on the GPRs. Yuck! */
15218 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15219 && FLOAT_MODE_P (mode))
15221 rtx cmp, or_result, compare_result2;
15222 enum machine_mode op_mode = GET_MODE (op0);
15224 if (op_mode == VOIDmode)
15225 op_mode = GET_MODE (op1);
15227 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15228 This explains the following mess. */
15232 case EQ: case UNEQ: case NE: case LTGT:
15236 cmp = (flag_finite_math_only && !flag_trapping_math)
15237 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15238 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15242 cmp = (flag_finite_math_only && !flag_trapping_math)
15243 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15244 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15248 cmp = (flag_finite_math_only && !flag_trapping_math)
15249 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15250 : gen_cmptfeq_gpr (compare_result, op0, op1);
15254 gcc_unreachable ();
15258 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15262 cmp = (flag_finite_math_only && !flag_trapping_math)
15263 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15264 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15268 cmp = (flag_finite_math_only && !flag_trapping_math)
15269 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15270 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15274 cmp = (flag_finite_math_only && !flag_trapping_math)
15275 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15276 : gen_cmptfgt_gpr (compare_result, op0, op1);
15280 gcc_unreachable ();
15284 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15288 cmp = (flag_finite_math_only && !flag_trapping_math)
15289 ? gen_tstsflt_gpr (compare_result, op0, op1)
15290 : gen_cmpsflt_gpr (compare_result, op0, op1);
15294 cmp = (flag_finite_math_only && !flag_trapping_math)
15295 ? gen_tstdflt_gpr (compare_result, op0, op1)
15296 : gen_cmpdflt_gpr (compare_result, op0, op1);
15300 cmp = (flag_finite_math_only && !flag_trapping_math)
15301 ? gen_tsttflt_gpr (compare_result, op0, op1)
15302 : gen_cmptflt_gpr (compare_result, op0, op1);
15306 gcc_unreachable ();
15310 gcc_unreachable ();
15313 /* Synthesize LE and GE from LT/GT || EQ. */
15314 if (code == LE || code == GE || code == LEU || code == GEU)
15320 case LE: code = LT; break;
15321 case GE: code = GT; break;
15322 case LEU: code = LT; break;
15323 case GEU: code = GT; break;
15324 default: gcc_unreachable ();
15327 compare_result2 = gen_reg_rtx (CCFPmode);
15333 cmp = (flag_finite_math_only && !flag_trapping_math)
15334 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15335 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15339 cmp = (flag_finite_math_only && !flag_trapping_math)
15340 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15341 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15345 cmp = (flag_finite_math_only && !flag_trapping_math)
15346 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15347 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15351 gcc_unreachable ();
15355 /* OR them together. */
15356 or_result = gen_reg_rtx (CCFPmode);
15357 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15359 compare_result = or_result;
15364 if (code == NE || code == LTGT)
15374 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15375 CLOBBERs to match cmptf_internal2 pattern. */
15376 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15377 && GET_MODE (op0) == TFmode
15378 && !TARGET_IEEEQUAD
15379 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15380 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15382 gen_rtx_SET (VOIDmode,
15384 gen_rtx_COMPARE (comp_mode, op0, op1)),
15385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15386 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15387 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15388 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15390 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15391 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15392 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15393 else if (GET_CODE (op1) == UNSPEC
15394 && XINT (op1, 1) == UNSPEC_SP_TEST)
15396 rtx op1b = XVECEXP (op1, 0, 0);
15397 comp_mode = CCEQmode;
15398 compare_result = gen_reg_rtx (CCEQmode);
15400 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15402 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15405 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15406 gen_rtx_COMPARE (comp_mode, op0, op1)));
15409 /* Some kinds of FP comparisons need an OR operation;
15410 under flag_finite_math_only we don't bother. */
15411 if (FLOAT_MODE_P (mode)
15412 && !flag_finite_math_only
15413 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15414 && (code == LE || code == GE
15415 || code == UNEQ || code == LTGT
15416 || code == UNGT || code == UNLT))
15418 enum rtx_code or1, or2;
15419 rtx or1_rtx, or2_rtx, compare2_rtx;
15420 rtx or_result = gen_reg_rtx (CCEQmode);
15424 case LE: or1 = LT; or2 = EQ; break;
15425 case GE: or1 = GT; or2 = EQ; break;
15426 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15427 case LTGT: or1 = LT; or2 = GT; break;
15428 case UNGT: or1 = UNORDERED; or2 = GT; break;
15429 case UNLT: or1 = UNORDERED; or2 = LT; break;
15430 default: gcc_unreachable ();
15432 validate_condition_mode (or1, comp_mode);
15433 validate_condition_mode (or2, comp_mode);
15434 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15435 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15436 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15437 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15439 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15441 compare_result = or_result;
15445 validate_condition_mode (code, GET_MODE (compare_result));
15447 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15451 /* Emit the RTL for an sCOND pattern. */
15454 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15457 enum machine_mode op_mode;
15458 enum rtx_code cond_code;
15459 rtx result = operands[0];
15461 condition_rtx = rs6000_generate_compare (operands[1], mode);
15462 cond_code = GET_CODE (condition_rtx);
15464 op_mode = GET_MODE (XEXP (operands[1], 0));
15465 if (op_mode == VOIDmode)
15466 op_mode = GET_MODE (XEXP (operands[1], 1));
15468 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15470 PUT_MODE (condition_rtx, DImode);
15471 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15472 || cond_code == LTU)
15473 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15474 force_reg (DImode, const1_rtx),
15475 force_reg (DImode, const0_rtx),
15476 XEXP (condition_rtx, 0)));
15478 emit_insn (gen_isel_signed_di (result, condition_rtx,
15479 force_reg (DImode, const1_rtx),
15480 force_reg (DImode, const0_rtx),
15481 XEXP (condition_rtx, 0)));
15485 PUT_MODE (condition_rtx, SImode);
15486 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15487 || cond_code == LTU)
15488 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15489 force_reg (SImode, const1_rtx),
15490 force_reg (SImode, const0_rtx),
15491 XEXP (condition_rtx, 0)));
15493 emit_insn (gen_isel_signed_si (result, condition_rtx,
15494 force_reg (SImode, const1_rtx),
15495 force_reg (SImode, const0_rtx),
15496 XEXP (condition_rtx, 0)));
15501 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15504 enum machine_mode op_mode;
15505 enum rtx_code cond_code;
15506 rtx result = operands[0];
15508 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15510 rs6000_emit_sISEL (mode, operands);
15514 condition_rtx = rs6000_generate_compare (operands[1], mode);
15515 cond_code = GET_CODE (condition_rtx);
15517 if (FLOAT_MODE_P (mode)
15518 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15522 PUT_MODE (condition_rtx, SImode);
15523 t = XEXP (condition_rtx, 0);
15525 gcc_assert (cond_code == NE || cond_code == EQ);
15527 if (cond_code == NE)
15528 emit_insn (gen_e500_flip_gt_bit (t, t));
15530 emit_insn (gen_move_from_CR_gt_bit (result, t));
15534 if (cond_code == NE
15535 || cond_code == GE || cond_code == LE
15536 || cond_code == GEU || cond_code == LEU
15537 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15539 rtx not_result = gen_reg_rtx (CCEQmode);
15540 rtx not_op, rev_cond_rtx;
15541 enum machine_mode cc_mode;
15543 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15545 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15546 SImode, XEXP (condition_rtx, 0), const0_rtx);
15547 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15548 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15549 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15552 op_mode = GET_MODE (XEXP (operands[1], 0));
15553 if (op_mode == VOIDmode)
15554 op_mode = GET_MODE (XEXP (operands[1], 1));
15556 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15558 PUT_MODE (condition_rtx, DImode);
15559 convert_move (result, condition_rtx, 0);
15563 PUT_MODE (condition_rtx, SImode);
15564 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15568 /* Emit a branch of kind CODE to location LOC. */
15571 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15573 rtx condition_rtx, loc_ref;
15575 condition_rtx = rs6000_generate_compare (operands[0], mode);
15576 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15577 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15578 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15579 loc_ref, pc_rtx)));
15582 /* Return the string to output a conditional branch to LABEL, which is
15583 the operand number of the label, or -1 if the branch is really a
15584 conditional return.
15586 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15587 condition code register and its mode specifies what kind of
15588 comparison we made.
15590 REVERSED is nonzero if we should reverse the sense of the comparison.
15592 INSN is the insn. */
15595 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15597 static char string[64];
15598 enum rtx_code code = GET_CODE (op);
15599 rtx cc_reg = XEXP (op, 0);
15600 enum machine_mode mode = GET_MODE (cc_reg);
15601 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15602 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15603 int really_reversed = reversed ^ need_longbranch;
15609 validate_condition_mode (code, mode);
15611 /* Work out which way this really branches. We could use
15612 reverse_condition_maybe_unordered here always but this
15613 makes the resulting assembler clearer. */
15614 if (really_reversed)
15616 /* Reversal of FP compares takes care -- an ordered compare
15617 becomes an unordered compare and vice versa. */
15618 if (mode == CCFPmode)
15619 code = reverse_condition_maybe_unordered (code);
15621 code = reverse_condition (code);
15624 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15626 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15631 /* Opposite of GT. */
15640 gcc_unreachable ();
15646 /* Not all of these are actually distinct opcodes, but
15647 we distinguish them for clarity of the resulting assembler. */
15648 case NE: case LTGT:
15649 ccode = "ne"; break;
15650 case EQ: case UNEQ:
15651 ccode = "eq"; break;
15653 ccode = "ge"; break;
15654 case GT: case GTU: case UNGT:
15655 ccode = "gt"; break;
15657 ccode = "le"; break;
15658 case LT: case LTU: case UNLT:
15659 ccode = "lt"; break;
15660 case UNORDERED: ccode = "un"; break;
15661 case ORDERED: ccode = "nu"; break;
15662 case UNGE: ccode = "nl"; break;
15663 case UNLE: ccode = "ng"; break;
15665 gcc_unreachable ();
15668 /* Maybe we have a guess as to how likely the branch is.
15669 The old mnemonics don't have a way to specify this information. */
15671 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15672 if (note != NULL_RTX)
15674 /* PROB is the difference from 50%. */
15675 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15677 /* Only hint for highly probable/improbable branches on newer
15678 cpus as static prediction overrides processor dynamic
15679 prediction. For older cpus we may as well always hint, but
15680 assume not taken for branches that are very close to 50% as a
15681 mispredicted taken branch is more expensive than a
15682 mispredicted not-taken branch. */
15683 if (rs6000_always_hint
15684 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15685 && br_prob_note_reliable_p (note)))
15687 if (abs (prob) > REG_BR_PROB_BASE / 20
15688 && ((prob > 0) ^ need_longbranch))
15696 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15698 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15700 /* We need to escape any '%' characters in the reg_names string.
15701 Assume they'd only be the first character.... */
15702 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15704 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15708 /* If the branch distance was too far, we may have to use an
15709 unconditional branch to go the distance. */
15710 if (need_longbranch)
15711 s += sprintf (s, ",$+8\n\tb %s", label);
15713 s += sprintf (s, ",%s", label);
15719 /* Return the string to flip the GT bit on a CR. */
15721 output_e500_flip_gt_bit (rtx dst, rtx src)
15723 static char string[64];
15726 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15727 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15730 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15731 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15733 sprintf (string, "crnot %d,%d", a, b);
15737 /* Return insn for VSX or Altivec comparisons. */
15740 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15743 enum machine_mode mode = GET_MODE (op0);
15751 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15757 mask = gen_reg_rtx (mode);
15758 emit_insn (gen_rtx_SET (VOIDmode,
15760 gen_rtx_fmt_ee (code, mode, op0, op1)));
15767 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15768 DMODE is expected destination mode. This is a recursive function. */
15771 rs6000_emit_vector_compare (enum rtx_code rcode,
15773 enum machine_mode dmode)
15776 bool swap_operands = false;
15777 bool try_again = false;
15779 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15780 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15782 /* See if the comparison works as is. */
15783 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15791 swap_operands = true;
15796 swap_operands = true;
15804 /* Invert condition and try again.
15805 e.g., A != B becomes ~(A==B). */
15807 enum rtx_code rev_code;
15808 enum insn_code nor_code;
15811 rev_code = reverse_condition_maybe_unordered (rcode);
15812 if (rev_code == UNKNOWN)
15815 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15816 if (nor_code == CODE_FOR_nothing)
15819 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15823 mask = gen_reg_rtx (dmode);
15824 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15832 /* Try GT/GTU/LT/LTU OR EQ */
15835 enum insn_code ior_code;
15836 enum rtx_code new_code;
15857 gcc_unreachable ();
15860 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15861 if (ior_code == CODE_FOR_nothing)
15864 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15868 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15872 mask = gen_reg_rtx (dmode);
15873 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15891 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15896 /* You only get two chances. */
15900 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15901 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15902 operands for the relation operation COND. */
15905 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15906 rtx cond, rtx cc_op0, rtx cc_op1)
15908 enum machine_mode dest_mode = GET_MODE (dest);
15909 enum rtx_code rcode = GET_CODE (cond);
15910 enum machine_mode cc_mode = CCmode;
15914 bool invert_move = false;
15916 if (VECTOR_UNIT_NONE_P (dest_mode))
15921 /* Swap operands if we can, and fall back to doing the operation as
15922 specified, and doing a NOR to invert the test. */
15928 /* Invert condition and try again.
15929 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15930 invert_move = true;
15931 rcode = reverse_condition_maybe_unordered (rcode);
15932 if (rcode == UNKNOWN)
15936 /* Mark unsigned tests with CCUNSmode. */
15941 cc_mode = CCUNSmode;
15948 /* Get the vector mask for the given relational operations. */
15949 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15957 op_true = op_false;
15961 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15962 emit_insn (gen_rtx_SET (VOIDmode,
15964 gen_rtx_IF_THEN_ELSE (dest_mode,
15971 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15972 operands of the last comparison is nonzero/true, FALSE_COND if it
15973 is zero/false. Return 0 if the hardware has no such operation. */
15976 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15978 enum rtx_code code = GET_CODE (op);
15979 rtx op0 = XEXP (op, 0);
15980 rtx op1 = XEXP (op, 1);
15981 REAL_VALUE_TYPE c1;
15982 enum machine_mode compare_mode = GET_MODE (op0);
15983 enum machine_mode result_mode = GET_MODE (dest);
15985 bool is_against_zero;
15987 /* These modes should always match. */
15988 if (GET_MODE (op1) != compare_mode
15989 /* In the isel case however, we can use a compare immediate, so
15990 op1 may be a small constant. */
15991 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15993 if (GET_MODE (true_cond) != result_mode)
15995 if (GET_MODE (false_cond) != result_mode)
15998 /* First, work out if the hardware can do this at all, or
15999 if it's too slow.... */
16000 if (!FLOAT_MODE_P (compare_mode))
16003 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16006 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16007 && SCALAR_FLOAT_MODE_P (compare_mode))
16010 is_against_zero = op1 == CONST0_RTX (compare_mode);
16012 /* A floating-point subtract might overflow, underflow, or produce
16013 an inexact result, thus changing the floating-point flags, so it
16014 can't be generated if we care about that. It's safe if one side
16015 of the construct is zero, since then no subtract will be
16017 if (SCALAR_FLOAT_MODE_P (compare_mode)
16018 && flag_trapping_math && ! is_against_zero)
16021 /* Eliminate half of the comparisons by switching operands, this
16022 makes the remaining code simpler. */
16023 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16024 || code == LTGT || code == LT || code == UNLE)
16026 code = reverse_condition_maybe_unordered (code);
16028 true_cond = false_cond;
16032 /* UNEQ and LTGT take four instructions for a comparison with zero,
16033 it'll probably be faster to use a branch here too. */
16034 if (code == UNEQ && HONOR_NANS (compare_mode))
16037 if (GET_CODE (op1) == CONST_DOUBLE)
16038 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16040 /* We're going to try to implement comparisons by performing
16041 a subtract, then comparing against zero. Unfortunately,
16042 Inf - Inf is NaN which is not zero, and so if we don't
16043 know that the operand is finite and the comparison
16044 would treat EQ different to UNORDERED, we can't do it. */
16045 if (HONOR_INFINITIES (compare_mode)
16046 && code != GT && code != UNGE
16047 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16048 /* Constructs of the form (a OP b ? a : b) are safe. */
16049 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16050 || (! rtx_equal_p (op0, true_cond)
16051 && ! rtx_equal_p (op1, true_cond))))
16054 /* At this point we know we can use fsel. */
16056 /* Reduce the comparison to a comparison against zero. */
16057 if (! is_against_zero)
16059 temp = gen_reg_rtx (compare_mode);
16060 emit_insn (gen_rtx_SET (VOIDmode, temp,
16061 gen_rtx_MINUS (compare_mode, op0, op1)));
16063 op1 = CONST0_RTX (compare_mode);
16066 /* If we don't care about NaNs we can reduce some of the comparisons
16067 down to faster ones. */
16068 if (! HONOR_NANS (compare_mode))
16074 true_cond = false_cond;
16087 /* Now, reduce everything down to a GE. */
16094 temp = gen_reg_rtx (compare_mode);
16095 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16100 temp = gen_reg_rtx (compare_mode);
16101 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16106 temp = gen_reg_rtx (compare_mode);
16107 emit_insn (gen_rtx_SET (VOIDmode, temp,
16108 gen_rtx_NEG (compare_mode,
16109 gen_rtx_ABS (compare_mode, op0))));
16114 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16115 temp = gen_reg_rtx (result_mode);
16116 emit_insn (gen_rtx_SET (VOIDmode, temp,
16117 gen_rtx_IF_THEN_ELSE (result_mode,
16118 gen_rtx_GE (VOIDmode,
16120 true_cond, false_cond)));
16121 false_cond = true_cond;
16124 temp = gen_reg_rtx (compare_mode);
16125 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16130 /* a GT 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 true_cond = false_cond;
16140 temp = gen_reg_rtx (compare_mode);
16141 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16146 gcc_unreachable ();
16149 emit_insn (gen_rtx_SET (VOIDmode, dest,
16150 gen_rtx_IF_THEN_ELSE (result_mode,
16151 gen_rtx_GE (VOIDmode,
16153 true_cond, false_cond)));
16157 /* Same as above, but for ints (isel). */
16160 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16162 rtx condition_rtx, cr;
16163 enum machine_mode mode = GET_MODE (dest);
16165 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16168 /* We still have to do the compare, because isel doesn't do a
16169 compare, it just looks at the CRx bits set by a previous compare
16171 condition_rtx = rs6000_generate_compare (op, mode);
16172 cr = XEXP (condition_rtx, 0);
16174 if (mode == SImode)
16176 if (GET_MODE (cr) == CCmode)
16177 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16178 true_cond, false_cond, cr));
16180 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16181 true_cond, false_cond, cr));
16185 if (GET_MODE (cr) == CCmode)
16186 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16187 true_cond, false_cond, cr));
16189 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16190 true_cond, false_cond, cr));
16197 output_isel (rtx *operands)
16199 enum rtx_code code;
16201 code = GET_CODE (operands[1]);
16202 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16204 PUT_CODE (operands[1], reverse_condition (code));
16205 return "isel %0,%3,%2,%j1";
16208 return "isel %0,%2,%3,%j1";
16212 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16214 enum machine_mode mode = GET_MODE (op0);
16218 /* VSX/altivec have direct min/max insns. */
16219 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16221 emit_insn (gen_rtx_SET (VOIDmode,
16223 gen_rtx_fmt_ee (code, mode, op0, op1)));
16227 if (code == SMAX || code == SMIN)
16232 if (code == SMAX || code == UMAX)
16233 target = emit_conditional_move (dest, c, op0, op1, mode,
16234 op0, op1, mode, 0);
16236 target = emit_conditional_move (dest, c, op0, op1, mode,
16237 op1, op0, mode, 0);
16238 gcc_assert (target);
16239 if (target != dest)
16240 emit_move_insn (dest, target);
16243 /* Emit instructions to perform a load-reserved/store-conditional operation.
16244 The operation performed is an atomic
16245 (set M (CODE:MODE M OP))
16246 If not NULL, BEFORE is atomically set to M before the operation, and
16247 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16248 If SYNC_P then a memory barrier is emitted before the operation.
16249 Either OP or M may be wrapped in a NOT operation. */
16252 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16253 rtx m, rtx op, rtx before_param, rtx after_param,
16256 enum machine_mode used_mode;
16257 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16260 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16261 rtx shift = NULL_RTX;
16264 emit_insn (gen_lwsync ());
16268 /* If this is smaller than SImode, we'll have to use SImode with
16270 if (mode == QImode || mode == HImode)
16274 if (MEM_ALIGN (used_m) >= 32)
16277 if (BYTES_BIG_ENDIAN)
16278 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16280 shift = GEN_INT (ishift);
16281 used_m = change_address (used_m, SImode, 0);
16285 rtx addrSI, aligned_addr;
16286 int shift_mask = mode == QImode ? 0x18 : 0x10;
16288 addrSI = gen_lowpart_common (SImode,
16289 force_reg (Pmode, XEXP (used_m, 0)));
16290 addrSI = force_reg (SImode, addrSI);
16291 shift = gen_reg_rtx (SImode);
16293 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16294 GEN_INT (shift_mask)));
16295 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16297 aligned_addr = expand_binop (Pmode, and_optab,
16299 GEN_INT (-4), NULL_RTX,
16300 1, OPTAB_LIB_WIDEN);
16301 used_m = change_address (used_m, SImode, aligned_addr);
16302 set_mem_align (used_m, 32);
16304 /* It's safe to keep the old alias set of USED_M, because
16305 the operation is atomic and only affects the original
16309 if (GET_CODE (op) == NOT)
16311 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16312 oldop = gen_rtx_NOT (SImode, oldop);
16315 oldop = lowpart_subreg (SImode, op, mode);
16321 newop = expand_binop (SImode, and_optab,
16322 oldop, GEN_INT (imask), NULL_RTX,
16323 1, OPTAB_LIB_WIDEN);
16324 emit_insn (gen_ashlsi3 (newop, newop, shift));
16327 case NOT: /* NAND */
16328 newop = expand_binop (SImode, ior_optab,
16329 oldop, GEN_INT (~imask), NULL_RTX,
16330 1, OPTAB_LIB_WIDEN);
16331 emit_insn (gen_rotlsi3 (newop, newop, shift));
16335 newop = expand_binop (SImode, ior_optab,
16336 oldop, GEN_INT (~imask), NULL_RTX,
16337 1, OPTAB_LIB_WIDEN);
16338 emit_insn (gen_rotlsi3 (newop, newop, shift));
16346 newop = expand_binop (SImode, and_optab,
16347 oldop, GEN_INT (imask), NULL_RTX,
16348 1, OPTAB_LIB_WIDEN);
16349 emit_insn (gen_ashlsi3 (newop, newop, shift));
16351 mask = gen_reg_rtx (SImode);
16352 emit_move_insn (mask, GEN_INT (imask));
16353 emit_insn (gen_ashlsi3 (mask, mask, shift));
16356 newop = gen_rtx_PLUS (SImode, m, newop);
16358 newop = gen_rtx_MINUS (SImode, m, newop);
16359 newop = gen_rtx_AND (SImode, newop, mask);
16360 newop = gen_rtx_IOR (SImode, newop,
16361 gen_rtx_AND (SImode,
16362 gen_rtx_NOT (SImode, mask),
16368 gcc_unreachable ();
16372 used_mode = SImode;
16373 before = gen_reg_rtx (used_mode);
16374 after = gen_reg_rtx (used_mode);
16379 before = before_param;
16380 after = after_param;
16382 if (before == NULL_RTX)
16383 before = gen_reg_rtx (used_mode);
16384 if (after == NULL_RTX)
16385 after = gen_reg_rtx (used_mode);
16388 if ((code == PLUS || code == MINUS)
16389 && used_mode != mode)
16390 the_op = op; /* Computed above. */
16391 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16392 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16393 else if (code == NOT)
16394 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16395 gen_rtx_NOT (used_mode, m),
16396 gen_rtx_NOT (used_mode, op));
16398 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16400 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16401 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16402 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16403 gen_rtx_UNSPEC (used_mode,
16404 gen_rtvec (1, the_op),
16406 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16408 if ((code == PLUS || code == MINUS) && used_mode != mode)
16409 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16410 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16412 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16413 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16415 /* Shift and mask the return values properly. */
16416 if (used_mode != mode && before_param)
16418 emit_insn (gen_lshrsi3 (before, before, shift));
16419 convert_move (before_param, before, 1);
16422 if (used_mode != mode && after_param)
16424 emit_insn (gen_lshrsi3 (after, after, shift));
16425 convert_move (after_param, after, 1);
16428 /* The previous sequence will end with a branch that's dependent on
16429 the conditional store, so placing an isync will ensure that no
16430 other instructions (especially, no load or store instructions)
16431 can start before the atomic operation completes. */
16433 emit_insn (gen_isync ());
16436 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16437 COND is true. Mark the jump as unlikely to be taken. */
16440 emit_unlikely_jump (rtx cond, rtx label)
16442 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16445 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16446 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16447 add_reg_note (x, REG_BR_PROB, very_unlikely);
16450 /* A subroutine of the atomic operation splitters. Emit a load-locked
16451 instruction in MODE. */
16454 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16456 rtx (*fn) (rtx, rtx) = NULL;
16457 if (mode == SImode)
16458 fn = gen_load_locked_si;
16459 else if (mode == DImode)
16460 fn = gen_load_locked_di;
16461 emit_insn (fn (reg, mem));
16464 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16465 instruction in MODE. */
16468 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16470 rtx (*fn) (rtx, rtx, rtx) = NULL;
16471 if (mode == SImode)
16472 fn = gen_store_conditional_si;
16473 else if (mode == DImode)
16474 fn = gen_store_conditional_di;
16476 /* Emit sync before stwcx. to address PPC405 Erratum. */
16477 if (PPC405_ERRATUM77)
16478 emit_insn (gen_memory_barrier ());
16480 emit_insn (fn (res, mem, val));
16483 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16484 to perform. MEM is the memory on which to operate. VAL is the second
16485 operand of the binary operator. BEFORE and AFTER are optional locations to
16486 return the value of MEM either before of after the operation. SCRATCH is
16487 a scratch register. */
16490 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16491 rtx before, rtx after, rtx scratch)
16493 enum machine_mode mode = GET_MODE (mem);
16494 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16496 emit_insn (gen_lwsync ());
16498 label = gen_label_rtx ();
16499 emit_label (label);
16500 label = gen_rtx_LABEL_REF (VOIDmode, label);
16502 if (before == NULL_RTX)
16504 emit_load_locked (mode, before, mem);
16507 x = gen_rtx_IOR (mode,
16508 gen_rtx_NOT (mode, before),
16509 gen_rtx_NOT (mode, val));
16510 else if (code == AND)
16511 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16513 x = gen_rtx_fmt_ee (code, mode, before, val);
16515 if (after != NULL_RTX)
16516 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16517 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16519 emit_store_conditional (mode, cond, mem, scratch);
16521 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16522 emit_unlikely_jump (x, label);
16524 emit_insn (gen_isync ());
16527 /* Expand an atomic compare and swap operation. MEM is the memory on which
16528 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16529 value to be stored. SCRATCH is a scratch GPR. */
16532 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16535 enum machine_mode mode = GET_MODE (mem);
16536 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16538 emit_insn (gen_lwsync ());
16540 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16541 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16542 emit_label (XEXP (label1, 0));
16544 emit_load_locked (mode, retval, mem);
16546 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16547 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16549 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16550 emit_unlikely_jump (x, label2);
16552 emit_move_insn (scratch, newval);
16553 emit_store_conditional (mode, cond, mem, scratch);
16555 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16556 emit_unlikely_jump (x, label1);
16558 emit_insn (gen_isync ());
16559 emit_label (XEXP (label2, 0));
16562 /* Expand an atomic test and set operation. MEM is the memory on which
16563 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16566 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16568 enum machine_mode mode = GET_MODE (mem);
16569 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16571 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16572 emit_label (XEXP (label, 0));
16574 emit_load_locked (mode, retval, mem);
16575 emit_move_insn (scratch, val);
16576 emit_store_conditional (mode, cond, mem, scratch);
16578 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16579 emit_unlikely_jump (x, label);
16581 emit_insn (gen_isync ());
16585 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16587 enum machine_mode mode = GET_MODE (mem);
16588 rtx addrSI, align, wdst, shift, mask;
16589 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16590 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16592 /* Shift amount for subword relative to aligned word. */
16593 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16594 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16595 shift = gen_reg_rtx (SImode);
16596 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16597 GEN_INT (shift_mask)));
16598 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16600 /* Shift and mask old value into position within word. */
16601 oldval = convert_modes (SImode, mode, oldval, 1);
16602 oldval = expand_binop (SImode, and_optab,
16603 oldval, GEN_INT (imask), NULL_RTX,
16604 1, OPTAB_LIB_WIDEN);
16605 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16607 /* Shift and mask new value into position within word. */
16608 newval = convert_modes (SImode, mode, newval, 1);
16609 newval = expand_binop (SImode, and_optab,
16610 newval, GEN_INT (imask), NULL_RTX,
16611 1, OPTAB_LIB_WIDEN);
16612 emit_insn (gen_ashlsi3 (newval, newval, shift));
16614 /* Mask for insertion. */
16615 mask = gen_reg_rtx (SImode);
16616 emit_move_insn (mask, GEN_INT (imask));
16617 emit_insn (gen_ashlsi3 (mask, mask, shift));
16619 /* Address of aligned word containing subword. */
16620 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16621 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16622 mem = change_address (mem, SImode, align);
16623 set_mem_align (mem, 32);
16624 MEM_VOLATILE_P (mem) = 1;
16626 wdst = gen_reg_rtx (SImode);
16627 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16628 oldval, newval, mem));
16630 /* Shift the result back. */
16631 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16633 emit_move_insn (dst, gen_lowpart (mode, wdst));
16637 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16638 rtx oldval, rtx newval, rtx mem,
16641 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16643 emit_insn (gen_lwsync ());
16644 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16645 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16646 emit_label (XEXP (label1, 0));
16648 emit_load_locked (SImode, scratch, mem);
16650 /* Mask subword within loaded value for comparison with oldval.
16651 Use UNSPEC_AND to avoid clobber.*/
16652 emit_insn (gen_rtx_SET (SImode, dest,
16653 gen_rtx_UNSPEC (SImode,
16654 gen_rtvec (2, scratch, mask),
16657 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16658 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16660 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16661 emit_unlikely_jump (x, label2);
16663 /* Clear subword within loaded value for insertion of new value. */
16664 emit_insn (gen_rtx_SET (SImode, scratch,
16665 gen_rtx_AND (SImode,
16666 gen_rtx_NOT (SImode, mask), scratch)));
16667 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16668 emit_store_conditional (SImode, cond, mem, scratch);
16670 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16671 emit_unlikely_jump (x, label1);
16673 emit_insn (gen_isync ());
16674 emit_label (XEXP (label2, 0));
16678 /* Emit instructions to move SRC to DST. Called by splitters for
16679 multi-register moves. It will emit at most one instruction for
16680 each register that is accessed; that is, it won't emit li/lis pairs
16681 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16685 rs6000_split_multireg_move (rtx dst, rtx src)
16687 /* The register number of the first register being moved. */
16689 /* The mode that is to be moved. */
16690 enum machine_mode mode;
16691 /* The mode that the move is being done in, and its size. */
16692 enum machine_mode reg_mode;
16694 /* The number of registers that will be moved. */
16697 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16698 mode = GET_MODE (dst);
16699 nregs = hard_regno_nregs[reg][mode];
16700 if (FP_REGNO_P (reg))
16701 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16702 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16703 else if (ALTIVEC_REGNO_P (reg))
16704 reg_mode = V16QImode;
16705 else if (TARGET_E500_DOUBLE && mode == TFmode)
16708 reg_mode = word_mode;
16709 reg_mode_size = GET_MODE_SIZE (reg_mode);
16711 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16713 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16715 /* Move register range backwards, if we might have destructive
16718 for (i = nregs - 1; i >= 0; i--)
16719 emit_insn (gen_rtx_SET (VOIDmode,
16720 simplify_gen_subreg (reg_mode, dst, mode,
16721 i * reg_mode_size),
16722 simplify_gen_subreg (reg_mode, src, mode,
16723 i * reg_mode_size)));
16729 bool used_update = false;
16730 rtx restore_basereg = NULL_RTX;
16732 if (MEM_P (src) && INT_REGNO_P (reg))
16736 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16737 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16740 breg = XEXP (XEXP (src, 0), 0);
16741 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16742 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16743 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16744 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16745 src = replace_equiv_address (src, breg);
16747 else if (! rs6000_offsettable_memref_p (src))
16749 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
16751 rtx basereg = XEXP (XEXP (src, 0), 0);
16754 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
16755 emit_insn (gen_rtx_SET (VOIDmode, ndst,
16756 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
16757 used_update = true;
16760 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16761 XEXP (XEXP (src, 0), 1)));
16762 src = replace_equiv_address (src, basereg);
16766 rtx basereg = gen_rtx_REG (Pmode, reg);
16767 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16768 src = replace_equiv_address (src, basereg);
16772 breg = XEXP (src, 0);
16773 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16774 breg = XEXP (breg, 0);
16776 /* If the base register we are using to address memory is
16777 also a destination reg, then change that register last. */
16779 && REGNO (breg) >= REGNO (dst)
16780 && REGNO (breg) < REGNO (dst) + nregs)
16781 j = REGNO (breg) - REGNO (dst);
16783 else if (MEM_P (dst) && INT_REGNO_P (reg))
16787 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16788 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16791 breg = XEXP (XEXP (dst, 0), 0);
16792 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16793 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16794 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16796 /* We have to update the breg before doing the store.
16797 Use store with update, if available. */
16801 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16802 emit_insn (TARGET_32BIT
16803 ? (TARGET_POWERPC64
16804 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16805 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16806 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16807 used_update = true;
16810 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16811 dst = replace_equiv_address (dst, breg);
16813 else if (!rs6000_offsettable_memref_p (dst)
16814 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
16816 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
16818 rtx basereg = XEXP (XEXP (dst, 0), 0);
16821 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16822 emit_insn (gen_rtx_SET (VOIDmode,
16823 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
16824 used_update = true;
16827 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16828 XEXP (XEXP (dst, 0), 1)));
16829 dst = replace_equiv_address (dst, basereg);
16833 rtx basereg = XEXP (XEXP (dst, 0), 0);
16834 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
16835 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
16836 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
16837 dst = replace_equiv_address (dst, basereg);
16840 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
16841 gcc_assert (rs6000_offsettable_memref_p (dst));
16844 for (i = 0; i < nregs; i++)
16846 /* Calculate index to next subword. */
16851 /* If compiler already emitted move of first word by
16852 store with update, no need to do anything. */
16853 if (j == 0 && used_update)
16856 emit_insn (gen_rtx_SET (VOIDmode,
16857 simplify_gen_subreg (reg_mode, dst, mode,
16858 j * reg_mode_size),
16859 simplify_gen_subreg (reg_mode, src, mode,
16860 j * reg_mode_size)));
16862 if (restore_basereg != NULL_RTX)
16863 emit_insn (restore_basereg);
16868 /* This page contains routines that are used to determine what the
16869 function prologue and epilogue code will do and write them out. */
16871 /* Return the first fixed-point register that is required to be
16872 saved. 32 if none. */
16875 first_reg_to_save (void)
16879 /* Find lowest numbered live register. */
16880 for (first_reg = 13; first_reg <= 31; first_reg++)
16881 if (df_regs_ever_live_p (first_reg)
16882 && (! call_used_regs[first_reg]
16883 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16884 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16885 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16886 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16891 && crtl->uses_pic_offset_table
16892 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16893 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16899 /* Similar, for FP regs. */
16902 first_fp_reg_to_save (void)
16906 /* Find lowest numbered live register. */
16907 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16908 if (df_regs_ever_live_p (first_reg))
16914 /* Similar, for AltiVec regs. */
16917 first_altivec_reg_to_save (void)
16921 /* Stack frame remains as is unless we are in AltiVec ABI. */
16922 if (! TARGET_ALTIVEC_ABI)
16923 return LAST_ALTIVEC_REGNO + 1;
16925 /* On Darwin, the unwind routines are compiled without
16926 TARGET_ALTIVEC, and use save_world to save/restore the
16927 altivec registers when necessary. */
16928 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16929 && ! TARGET_ALTIVEC)
16930 return FIRST_ALTIVEC_REGNO + 20;
16932 /* Find lowest numbered live register. */
16933 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16934 if (df_regs_ever_live_p (i))
16940 /* Return a 32-bit mask of the AltiVec registers we need to set in
16941 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16942 the 32-bit word is 0. */
16944 static unsigned int
16945 compute_vrsave_mask (void)
16947 unsigned int i, mask = 0;
16949 /* On Darwin, the unwind routines are compiled without
16950 TARGET_ALTIVEC, and use save_world to save/restore the
16951 call-saved altivec registers when necessary. */
16952 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16953 && ! TARGET_ALTIVEC)
16956 /* First, find out if we use _any_ altivec registers. */
16957 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16958 if (df_regs_ever_live_p (i))
16959 mask |= ALTIVEC_REG_BIT (i);
16964 /* Next, remove the argument registers from the set. These must
16965 be in the VRSAVE mask set by the caller, so we don't need to add
16966 them in again. More importantly, the mask we compute here is
16967 used to generate CLOBBERs in the set_vrsave insn, and we do not
16968 wish the argument registers to die. */
16969 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16970 mask &= ~ALTIVEC_REG_BIT (i);
16972 /* Similarly, remove the return value from the set. */
16975 diddle_return_value (is_altivec_return_reg, &yes);
16977 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16983 /* For a very restricted set of circumstances, we can cut down the
16984 size of prologues/epilogues by calling our own save/restore-the-world
16988 compute_save_world_info (rs6000_stack_t *info_ptr)
16990 info_ptr->world_save_p = 1;
16991 info_ptr->world_save_p
16992 = (WORLD_SAVE_P (info_ptr)
16993 && DEFAULT_ABI == ABI_DARWIN
16994 && ! (cfun->calls_setjmp && flag_exceptions)
16995 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16996 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16997 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16998 && info_ptr->cr_save_p);
17000 /* This will not work in conjunction with sibcalls. Make sure there
17001 are none. (This check is expensive, but seldom executed.) */
17002 if (WORLD_SAVE_P (info_ptr))
17005 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17006 if ( GET_CODE (insn) == CALL_INSN
17007 && SIBLING_CALL_P (insn))
17009 info_ptr->world_save_p = 0;
17014 if (WORLD_SAVE_P (info_ptr))
17016 /* Even if we're not touching VRsave, make sure there's room on the
17017 stack for it, if it looks like we're calling SAVE_WORLD, which
17018 will attempt to save it. */
17019 info_ptr->vrsave_size = 4;
17021 /* If we are going to save the world, we need to save the link register too. */
17022 info_ptr->lr_save_p = 1;
17024 /* "Save" the VRsave register too if we're saving the world. */
17025 if (info_ptr->vrsave_mask == 0)
17026 info_ptr->vrsave_mask = compute_vrsave_mask ();
17028 /* Because the Darwin register save/restore routines only handle
17029 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17031 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17032 && (info_ptr->first_altivec_reg_save
17033 >= FIRST_SAVED_ALTIVEC_REGNO));
17040 is_altivec_return_reg (rtx reg, void *xyes)
17042 bool *yes = (bool *) xyes;
17043 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17048 /* Calculate the stack information for the current function. This is
17049 complicated by having two separate calling sequences, the AIX calling
17050 sequence and the V.4 calling sequence.
17052 AIX (and Darwin/Mac OS X) stack frames look like:
17054 SP----> +---------------------------------------+
17055 | back chain to caller | 0 0
17056 +---------------------------------------+
17057 | saved CR | 4 8 (8-11)
17058 +---------------------------------------+
17060 +---------------------------------------+
17061 | reserved for compilers | 12 24
17062 +---------------------------------------+
17063 | reserved for binders | 16 32
17064 +---------------------------------------+
17065 | saved TOC pointer | 20 40
17066 +---------------------------------------+
17067 | Parameter save area (P) | 24 48
17068 +---------------------------------------+
17069 | Alloca space (A) | 24+P etc.
17070 +---------------------------------------+
17071 | Local variable space (L) | 24+P+A
17072 +---------------------------------------+
17073 | Float/int conversion temporary (X) | 24+P+A+L
17074 +---------------------------------------+
17075 | Save area for AltiVec registers (W) | 24+P+A+L+X
17076 +---------------------------------------+
17077 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17078 +---------------------------------------+
17079 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17080 +---------------------------------------+
17081 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17082 +---------------------------------------+
17083 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17084 +---------------------------------------+
17085 old SP->| back chain to caller's caller |
17086 +---------------------------------------+
17088 The required alignment for AIX configurations is two words (i.e., 8
17092 V.4 stack frames look like:
17094 SP----> +---------------------------------------+
17095 | back chain to caller | 0
17096 +---------------------------------------+
17097 | caller's saved LR | 4
17098 +---------------------------------------+
17099 | Parameter save area (P) | 8
17100 +---------------------------------------+
17101 | Alloca space (A) | 8+P
17102 +---------------------------------------+
17103 | Varargs save area (V) | 8+P+A
17104 +---------------------------------------+
17105 | Local variable space (L) | 8+P+A+V
17106 +---------------------------------------+
17107 | Float/int conversion temporary (X) | 8+P+A+V+L
17108 +---------------------------------------+
17109 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17110 +---------------------------------------+
17111 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17112 +---------------------------------------+
17113 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17114 +---------------------------------------+
17115 | SPE: area for 64-bit GP registers |
17116 +---------------------------------------+
17117 | SPE alignment padding |
17118 +---------------------------------------+
17119 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17120 +---------------------------------------+
17121 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17122 +---------------------------------------+
17123 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17124 +---------------------------------------+
17125 old SP->| back chain to caller's caller |
17126 +---------------------------------------+
17128 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17129 given. (But note below and in sysv4.h that we require only 8 and
17130 may round up the size of our stack frame anyways. The historical
17131 reason is early versions of powerpc-linux which didn't properly
17132 align the stack at program startup. A happy side-effect is that
17133 -mno-eabi libraries can be used with -meabi programs.)
17135 The EABI configuration defaults to the V.4 layout. However,
17136 the stack alignment requirements may differ. If -mno-eabi is not
17137 given, the required stack alignment is 8 bytes; if -mno-eabi is
17138 given, the required alignment is 16 bytes. (But see V.4 comment
17141 #ifndef ABI_STACK_BOUNDARY
17142 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17145 static rs6000_stack_t *
17146 rs6000_stack_info (void)
17148 static rs6000_stack_t info;
17149 rs6000_stack_t *info_ptr = &info;
17150 int reg_size = TARGET_32BIT ? 4 : 8;
17154 HOST_WIDE_INT non_fixed_size;
17156 memset (&info, 0, sizeof (info));
17160 /* Cache value so we don't rescan instruction chain over and over. */
17161 if (cfun->machine->insn_chain_scanned_p == 0)
17162 cfun->machine->insn_chain_scanned_p
17163 = spe_func_has_64bit_regs_p () + 1;
17164 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17167 /* Select which calling sequence. */
17168 info_ptr->abi = DEFAULT_ABI;
17170 /* Calculate which registers need to be saved & save area size. */
17171 info_ptr->first_gp_reg_save = first_reg_to_save ();
17172 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17173 even if it currently looks like we won't. Reload may need it to
17174 get at a constant; if so, it will have already created a constant
17175 pool entry for it. */
17176 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17177 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17178 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17179 && crtl->uses_const_pool
17180 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17181 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17183 first_gp = info_ptr->first_gp_reg_save;
17185 info_ptr->gp_size = reg_size * (32 - first_gp);
17187 /* For the SPE, we have an additional upper 32-bits on each GPR.
17188 Ideally we should save the entire 64-bits only when the upper
17189 half is used in SIMD instructions. Since we only record
17190 registers live (not the size they are used in), this proves
17191 difficult because we'd have to traverse the instruction chain at
17192 the right time, taking reload into account. This is a real pain,
17193 so we opt to save the GPRs in 64-bits always if but one register
17194 gets used in 64-bits. Otherwise, all the registers in the frame
17195 get saved in 32-bits.
17197 So... since when we save all GPRs (except the SP) in 64-bits, the
17198 traditional GP save area will be empty. */
17199 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17200 info_ptr->gp_size = 0;
17202 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17203 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17205 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17206 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17207 - info_ptr->first_altivec_reg_save);
17209 /* Does this function call anything? */
17210 info_ptr->calls_p = (! current_function_is_leaf
17211 || cfun->machine->ra_needs_full_frame);
17213 /* Determine if we need to save the link register. */
17214 if ((DEFAULT_ABI == ABI_AIX
17216 && !TARGET_PROFILE_KERNEL)
17217 #ifdef TARGET_RELOCATABLE
17218 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17220 || (info_ptr->first_fp_reg_save != 64
17221 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17222 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17223 || info_ptr->calls_p
17224 || rs6000_ra_ever_killed ())
17226 info_ptr->lr_save_p = 1;
17227 df_set_regs_ever_live (LR_REGNO, true);
17230 /* Determine if we need to save the condition code registers. */
17231 if (df_regs_ever_live_p (CR2_REGNO)
17232 || df_regs_ever_live_p (CR3_REGNO)
17233 || df_regs_ever_live_p (CR4_REGNO))
17235 info_ptr->cr_save_p = 1;
17236 if (DEFAULT_ABI == ABI_V4)
17237 info_ptr->cr_size = reg_size;
17240 /* If the current function calls __builtin_eh_return, then we need
17241 to allocate stack space for registers that will hold data for
17242 the exception handler. */
17243 if (crtl->calls_eh_return)
17246 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17249 /* SPE saves EH registers in 64-bits. */
17250 ehrd_size = i * (TARGET_SPE_ABI
17251 && info_ptr->spe_64bit_regs_used != 0
17252 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17257 /* Determine various sizes. */
17258 info_ptr->reg_size = reg_size;
17259 info_ptr->fixed_size = RS6000_SAVE_AREA;
17260 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17261 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17262 TARGET_ALTIVEC ? 16 : 8);
17263 if (FRAME_GROWS_DOWNWARD)
17264 info_ptr->vars_size
17265 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17266 + info_ptr->parm_size,
17267 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17268 - (info_ptr->fixed_size + info_ptr->vars_size
17269 + info_ptr->parm_size);
17271 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17272 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17274 info_ptr->spe_gp_size = 0;
17276 if (TARGET_ALTIVEC_ABI)
17277 info_ptr->vrsave_mask = compute_vrsave_mask ();
17279 info_ptr->vrsave_mask = 0;
17281 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17282 info_ptr->vrsave_size = 4;
17284 info_ptr->vrsave_size = 0;
17286 compute_save_world_info (info_ptr);
17288 /* Calculate the offsets. */
17289 switch (DEFAULT_ABI)
17293 gcc_unreachable ();
17297 info_ptr->fp_save_offset = - info_ptr->fp_size;
17298 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17300 if (TARGET_ALTIVEC_ABI)
17302 info_ptr->vrsave_save_offset
17303 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17305 /* Align stack so vector save area is on a quadword boundary.
17306 The padding goes above the vectors. */
17307 if (info_ptr->altivec_size != 0)
17308 info_ptr->altivec_padding_size
17309 = info_ptr->vrsave_save_offset & 0xF;
17311 info_ptr->altivec_padding_size = 0;
17313 info_ptr->altivec_save_offset
17314 = info_ptr->vrsave_save_offset
17315 - info_ptr->altivec_padding_size
17316 - info_ptr->altivec_size;
17317 gcc_assert (info_ptr->altivec_size == 0
17318 || info_ptr->altivec_save_offset % 16 == 0);
17320 /* Adjust for AltiVec case. */
17321 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17324 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17325 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17326 info_ptr->lr_save_offset = 2*reg_size;
17330 info_ptr->fp_save_offset = - info_ptr->fp_size;
17331 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17332 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17334 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17336 /* Align stack so SPE GPR save area is aligned on a
17337 double-word boundary. */
17338 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17339 info_ptr->spe_padding_size
17340 = 8 - (-info_ptr->cr_save_offset % 8);
17342 info_ptr->spe_padding_size = 0;
17344 info_ptr->spe_gp_save_offset
17345 = info_ptr->cr_save_offset
17346 - info_ptr->spe_padding_size
17347 - info_ptr->spe_gp_size;
17349 /* Adjust for SPE case. */
17350 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17352 else if (TARGET_ALTIVEC_ABI)
17354 info_ptr->vrsave_save_offset
17355 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17357 /* Align stack so vector save area is on a quadword boundary. */
17358 if (info_ptr->altivec_size != 0)
17359 info_ptr->altivec_padding_size
17360 = 16 - (-info_ptr->vrsave_save_offset % 16);
17362 info_ptr->altivec_padding_size = 0;
17364 info_ptr->altivec_save_offset
17365 = info_ptr->vrsave_save_offset
17366 - info_ptr->altivec_padding_size
17367 - info_ptr->altivec_size;
17369 /* Adjust for AltiVec case. */
17370 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17373 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17374 info_ptr->ehrd_offset -= ehrd_size;
17375 info_ptr->lr_save_offset = reg_size;
17379 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17380 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17381 + info_ptr->gp_size
17382 + info_ptr->altivec_size
17383 + info_ptr->altivec_padding_size
17384 + info_ptr->spe_gp_size
17385 + info_ptr->spe_padding_size
17387 + info_ptr->cr_size
17388 + info_ptr->vrsave_size,
17391 non_fixed_size = (info_ptr->vars_size
17392 + info_ptr->parm_size
17393 + info_ptr->save_size);
17395 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17396 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17398 /* Determine if we need to allocate any stack frame:
17400 For AIX we need to push the stack if a frame pointer is needed
17401 (because the stack might be dynamically adjusted), if we are
17402 debugging, if we make calls, or if the sum of fp_save, gp_save,
17403 and local variables are more than the space needed to save all
17404 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17405 + 18*8 = 288 (GPR13 reserved).
17407 For V.4 we don't have the stack cushion that AIX uses, but assume
17408 that the debugger can handle stackless frames. */
17410 if (info_ptr->calls_p)
17411 info_ptr->push_p = 1;
17413 else if (DEFAULT_ABI == ABI_V4)
17414 info_ptr->push_p = non_fixed_size != 0;
17416 else if (frame_pointer_needed)
17417 info_ptr->push_p = 1;
17419 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17420 info_ptr->push_p = 1;
17423 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17425 /* Zero offsets if we're not saving those registers. */
17426 if (info_ptr->fp_size == 0)
17427 info_ptr->fp_save_offset = 0;
17429 if (info_ptr->gp_size == 0)
17430 info_ptr->gp_save_offset = 0;
17432 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17433 info_ptr->altivec_save_offset = 0;
17435 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17436 info_ptr->vrsave_save_offset = 0;
17438 if (! TARGET_SPE_ABI
17439 || info_ptr->spe_64bit_regs_used == 0
17440 || info_ptr->spe_gp_size == 0)
17441 info_ptr->spe_gp_save_offset = 0;
17443 if (! info_ptr->lr_save_p)
17444 info_ptr->lr_save_offset = 0;
17446 if (! info_ptr->cr_save_p)
17447 info_ptr->cr_save_offset = 0;
17452 /* Return true if the current function uses any GPRs in 64-bit SIMD
17456 spe_func_has_64bit_regs_p (void)
17460 /* Functions that save and restore all the call-saved registers will
17461 need to save/restore the registers in 64-bits. */
17462 if (crtl->calls_eh_return
17463 || cfun->calls_setjmp
17464 || crtl->has_nonlocal_goto)
17467 insns = get_insns ();
17469 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17475 /* FIXME: This should be implemented with attributes...
17477 (set_attr "spe64" "true")....then,
17478 if (get_spe64(insn)) return true;
17480 It's the only reliable way to do the stuff below. */
17482 i = PATTERN (insn);
17483 if (GET_CODE (i) == SET)
17485 enum machine_mode mode = GET_MODE (SET_SRC (i));
17487 if (SPE_VECTOR_MODE (mode))
17489 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17499 debug_stack_info (rs6000_stack_t *info)
17501 const char *abi_string;
17504 info = rs6000_stack_info ();
17506 fprintf (stderr, "\nStack information for function %s:\n",
17507 ((current_function_decl && DECL_NAME (current_function_decl))
17508 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17513 default: abi_string = "Unknown"; break;
17514 case ABI_NONE: abi_string = "NONE"; break;
17515 case ABI_AIX: abi_string = "AIX"; break;
17516 case ABI_DARWIN: abi_string = "Darwin"; break;
17517 case ABI_V4: abi_string = "V.4"; break;
17520 fprintf (stderr, "\tABI = %5s\n", abi_string);
17522 if (TARGET_ALTIVEC_ABI)
17523 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17525 if (TARGET_SPE_ABI)
17526 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17528 if (info->first_gp_reg_save != 32)
17529 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17531 if (info->first_fp_reg_save != 64)
17532 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17534 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17535 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17536 info->first_altivec_reg_save);
17538 if (info->lr_save_p)
17539 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17541 if (info->cr_save_p)
17542 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17544 if (info->vrsave_mask)
17545 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17548 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17551 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17553 if (info->gp_save_offset)
17554 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17556 if (info->fp_save_offset)
17557 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17559 if (info->altivec_save_offset)
17560 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17561 info->altivec_save_offset);
17563 if (info->spe_gp_save_offset)
17564 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17565 info->spe_gp_save_offset);
17567 if (info->vrsave_save_offset)
17568 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17569 info->vrsave_save_offset);
17571 if (info->lr_save_offset)
17572 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17574 if (info->cr_save_offset)
17575 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17577 if (info->varargs_save_offset)
17578 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17580 if (info->total_size)
17581 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17584 if (info->vars_size)
17585 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17588 if (info->parm_size)
17589 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17591 if (info->fixed_size)
17592 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17595 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17597 if (info->spe_gp_size)
17598 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17601 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17603 if (info->altivec_size)
17604 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17606 if (info->vrsave_size)
17607 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17609 if (info->altivec_padding_size)
17610 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17611 info->altivec_padding_size);
17613 if (info->spe_padding_size)
17614 fprintf (stderr, "\tspe_padding_size = %5d\n",
17615 info->spe_padding_size);
17618 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17620 if (info->save_size)
17621 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17623 if (info->reg_size != 4)
17624 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17626 fprintf (stderr, "\n");
17630 rs6000_return_addr (int count, rtx frame)
17632 /* Currently we don't optimize very well between prolog and body
17633 code and for PIC code the code can be actually quite bad, so
17634 don't try to be too clever here. */
17635 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17637 cfun->machine->ra_needs_full_frame = 1;
17644 plus_constant (copy_to_reg
17645 (gen_rtx_MEM (Pmode,
17646 memory_address (Pmode, frame))),
17647 RETURN_ADDRESS_OFFSET)));
17650 cfun->machine->ra_need_lr = 1;
17651 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17654 /* Say whether a function is a candidate for sibcall handling or not.
17655 We do not allow indirect calls to be optimized into sibling calls.
17656 Also, we can't do it if there are any vector parameters; there's
17657 nowhere to put the VRsave code so it works; note that functions with
17658 vector parameters are required to have a prototype, so the argument
17659 type info must be available here. (The tail recursion case can work
17660 with vector parameters, but there's no way to distinguish here.) */
17662 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17667 if (TARGET_ALTIVEC_VRSAVE)
17669 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17670 type; type = TREE_CHAIN (type))
17672 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17676 if (DEFAULT_ABI == ABI_DARWIN
17677 || ((*targetm.binds_local_p) (decl)
17678 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17680 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17682 if (!lookup_attribute ("longcall", attr_list)
17683 || lookup_attribute ("shortcall", attr_list))
17690 /* NULL if INSN insn is valid within a low-overhead loop.
17691 Otherwise return why doloop cannot be applied.
17692 PowerPC uses the COUNT register for branch on table instructions. */
17694 static const char *
17695 rs6000_invalid_within_doloop (const_rtx insn)
17698 return "Function call in the loop.";
17701 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17702 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17703 return "Computed branch in the loop.";
17709 rs6000_ra_ever_killed (void)
17715 if (cfun->is_thunk)
17718 /* regs_ever_live has LR marked as used if any sibcalls are present,
17719 but this should not force saving and restoring in the
17720 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17721 clobbers LR, so that is inappropriate. */
17723 /* Also, the prologue can generate a store into LR that
17724 doesn't really count, like this:
17727 bcl to set PIC register
17731 When we're called from the epilogue, we need to avoid counting
17732 this as a store. */
17734 push_topmost_sequence ();
17735 top = get_insns ();
17736 pop_topmost_sequence ();
17737 reg = gen_rtx_REG (Pmode, LR_REGNO);
17739 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17745 if (!SIBLING_CALL_P (insn))
17748 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17750 else if (set_of (reg, insn) != NULL_RTX
17751 && !prologue_epilogue_contains (insn))
17758 /* Emit instructions needed to load the TOC register.
17759 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17760 a constant pool; or for SVR4 -fpic. */
17763 rs6000_emit_load_toc_table (int fromprolog)
17766 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17768 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17771 rtx lab, tmp1, tmp2, got;
17773 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17774 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17776 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17778 got = rs6000_got_sym ();
17779 tmp1 = tmp2 = dest;
17782 tmp1 = gen_reg_rtx (Pmode);
17783 tmp2 = gen_reg_rtx (Pmode);
17785 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17786 emit_move_insn (tmp1,
17787 gen_rtx_REG (Pmode, LR_REGNO));
17788 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17789 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17791 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17793 emit_insn (gen_load_toc_v4_pic_si ());
17794 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17796 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17799 rtx temp0 = (fromprolog
17800 ? gen_rtx_REG (Pmode, 0)
17801 : gen_reg_rtx (Pmode));
17807 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17808 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17810 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17811 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17813 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17814 emit_move_insn (dest,
17815 gen_rtx_REG (Pmode, LR_REGNO));
17816 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17822 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17823 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17824 emit_move_insn (dest,
17825 gen_rtx_REG (Pmode, LR_REGNO));
17826 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17828 emit_insn (gen_addsi3 (dest, temp0, dest));
17830 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17832 /* This is for AIX code running in non-PIC ELF32. */
17835 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17836 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17838 emit_insn (gen_elf_high (dest, realsym));
17839 emit_insn (gen_elf_low (dest, dest, realsym));
17843 gcc_assert (DEFAULT_ABI == ABI_AIX);
17846 emit_insn (gen_load_toc_aix_si (dest));
17848 emit_insn (gen_load_toc_aix_di (dest));
17852 /* Emit instructions to restore the link register after determining where
17853 its value has been stored. */
17856 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17858 rs6000_stack_t *info = rs6000_stack_info ();
17861 operands[0] = source;
17862 operands[1] = scratch;
17864 if (info->lr_save_p)
17866 rtx frame_rtx = stack_pointer_rtx;
17867 HOST_WIDE_INT sp_offset = 0;
17870 if (frame_pointer_needed
17871 || cfun->calls_alloca
17872 || info->total_size > 32767)
17874 tmp = gen_frame_mem (Pmode, frame_rtx);
17875 emit_move_insn (operands[1], tmp);
17876 frame_rtx = operands[1];
17878 else if (info->push_p)
17879 sp_offset = info->total_size;
17881 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17882 tmp = gen_frame_mem (Pmode, tmp);
17883 emit_move_insn (tmp, operands[0]);
17886 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17889 static GTY(()) alias_set_type set = -1;
17892 get_TOC_alias_set (void)
17895 set = new_alias_set ();
17899 /* This returns nonzero if the current function uses the TOC. This is
17900 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17901 is generated by the ABI_V4 load_toc_* patterns. */
17908 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17911 rtx pat = PATTERN (insn);
17914 if (GET_CODE (pat) == PARALLEL)
17915 for (i = 0; i < XVECLEN (pat, 0); i++)
17917 rtx sub = XVECEXP (pat, 0, i);
17918 if (GET_CODE (sub) == USE)
17920 sub = XEXP (sub, 0);
17921 if (GET_CODE (sub) == UNSPEC
17922 && XINT (sub, 1) == UNSPEC_TOC)
17932 create_TOC_reference (rtx symbol)
17934 if (TARGET_DEBUG_ADDR)
17936 if (GET_CODE (symbol) == SYMBOL_REF)
17937 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17941 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17942 GET_RTX_NAME (GET_CODE (symbol)));
17943 debug_rtx (symbol);
17947 if (!can_create_pseudo_p ())
17948 df_set_regs_ever_live (TOC_REGISTER, true);
17949 return gen_rtx_PLUS (Pmode,
17950 gen_rtx_REG (Pmode, TOC_REGISTER),
17951 gen_rtx_CONST (Pmode,
17952 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17955 /* Issue assembly directives that create a reference to the given DWARF
17956 FRAME_TABLE_LABEL from the current function section. */
17958 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17960 fprintf (asm_out_file, "\t.ref %s\n",
17961 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17964 /* If _Unwind_* has been called from within the same module,
17965 toc register is not guaranteed to be saved to 40(1) on function
17966 entry. Save it there in that case. */
17969 rs6000_aix_emit_builtin_unwind_init (void)
17972 rtx stack_top = gen_reg_rtx (Pmode);
17973 rtx opcode_addr = gen_reg_rtx (Pmode);
17974 rtx opcode = gen_reg_rtx (SImode);
17975 rtx tocompare = gen_reg_rtx (SImode);
17976 rtx no_toc_save_needed = gen_label_rtx ();
17978 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17979 emit_move_insn (stack_top, mem);
17981 mem = gen_frame_mem (Pmode,
17982 gen_rtx_PLUS (Pmode, stack_top,
17983 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17984 emit_move_insn (opcode_addr, mem);
17985 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17986 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17987 : 0xE8410028, SImode));
17989 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17990 SImode, NULL_RTX, NULL_RTX,
17991 no_toc_save_needed, -1);
17993 mem = gen_frame_mem (Pmode,
17994 gen_rtx_PLUS (Pmode, stack_top,
17995 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17996 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17997 emit_label (no_toc_save_needed);
18000 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18001 and the change to the stack pointer. */
18004 rs6000_emit_stack_tie (void)
18006 rtx mem = gen_frame_mem (BLKmode,
18007 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18009 emit_insn (gen_stack_tie (mem));
18012 /* Emit the correct code for allocating stack space, as insns.
18013 If COPY_R12, make sure a copy of the old frame is left in r12.
18014 If COPY_R11, make sure a copy of the old frame is left in r11,
18015 in preference to r12 if COPY_R12.
18016 The generated code may use hard register 0 as a temporary. */
18019 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
18022 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18023 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18024 rtx todec = gen_int_mode (-size, Pmode);
18027 if (INTVAL (todec) != -size)
18029 warning (0, "stack frame too large");
18030 emit_insn (gen_trap ());
18034 if (crtl->limit_stack)
18036 if (REG_P (stack_limit_rtx)
18037 && REGNO (stack_limit_rtx) > 1
18038 && REGNO (stack_limit_rtx) <= 31)
18040 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18041 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18044 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18046 && DEFAULT_ABI == ABI_V4)
18048 rtx toload = gen_rtx_CONST (VOIDmode,
18049 gen_rtx_PLUS (Pmode,
18053 emit_insn (gen_elf_high (tmp_reg, toload));
18054 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18055 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18059 warning (0, "stack limit expression is not supported");
18062 if (copy_r12 || copy_r11)
18063 emit_move_insn (copy_r11
18064 ? gen_rtx_REG (Pmode, 11)
18065 : gen_rtx_REG (Pmode, 12),
18070 /* Need a note here so that try_split doesn't get confused. */
18071 if (get_last_insn () == NULL_RTX)
18072 emit_note (NOTE_INSN_DELETED);
18073 insn = emit_move_insn (tmp_reg, todec);
18074 try_split (PATTERN (insn), insn, 0);
18078 insn = emit_insn (TARGET_32BIT
18079 ? gen_movsi_update_stack (stack_reg, stack_reg,
18081 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18082 todec, stack_reg));
18083 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18084 it now and set the alias set/attributes. The above gen_*_update
18085 calls will generate a PARALLEL with the MEM set being the first
18087 par = PATTERN (insn);
18088 gcc_assert (GET_CODE (par) == PARALLEL);
18089 set = XVECEXP (par, 0, 0);
18090 gcc_assert (GET_CODE (set) == SET);
18091 mem = SET_DEST (set);
18092 gcc_assert (MEM_P (mem));
18093 MEM_NOTRAP_P (mem) = 1;
18094 set_mem_alias_set (mem, get_frame_alias_set ());
18096 RTX_FRAME_RELATED_P (insn) = 1;
18097 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18098 gen_rtx_SET (VOIDmode, stack_reg,
18099 gen_rtx_PLUS (Pmode, stack_reg,
18100 GEN_INT (-size))));
18103 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18104 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18105 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18106 deduce these equivalences by itself so it wasn't necessary to hold
18107 its hand so much. */
18110 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18111 rtx reg2, rtx rreg)
18115 /* copy_rtx will not make unique copies of registers, so we need to
18116 ensure we don't have unwanted sharing here. */
18118 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18121 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18123 real = copy_rtx (PATTERN (insn));
18125 if (reg2 != NULL_RTX)
18126 real = replace_rtx (real, reg2, rreg);
18128 real = replace_rtx (real, reg,
18129 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18130 STACK_POINTER_REGNUM),
18133 /* We expect that 'real' is either a SET or a PARALLEL containing
18134 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18135 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18137 if (GET_CODE (real) == SET)
18141 temp = simplify_rtx (SET_SRC (set));
18143 SET_SRC (set) = temp;
18144 temp = simplify_rtx (SET_DEST (set));
18146 SET_DEST (set) = temp;
18147 if (GET_CODE (SET_DEST (set)) == MEM)
18149 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18151 XEXP (SET_DEST (set), 0) = temp;
18158 gcc_assert (GET_CODE (real) == PARALLEL);
18159 for (i = 0; i < XVECLEN (real, 0); i++)
18160 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18162 rtx set = XVECEXP (real, 0, i);
18164 temp = simplify_rtx (SET_SRC (set));
18166 SET_SRC (set) = temp;
18167 temp = simplify_rtx (SET_DEST (set));
18169 SET_DEST (set) = temp;
18170 if (GET_CODE (SET_DEST (set)) == MEM)
18172 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18174 XEXP (SET_DEST (set), 0) = temp;
18176 RTX_FRAME_RELATED_P (set) = 1;
18180 RTX_FRAME_RELATED_P (insn) = 1;
18181 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18184 /* Returns an insn that has a vrsave set operation with the
18185 appropriate CLOBBERs. */
18188 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18191 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18192 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18195 = gen_rtx_SET (VOIDmode,
18197 gen_rtx_UNSPEC_VOLATILE (SImode,
18198 gen_rtvec (2, reg, vrsave),
18199 UNSPECV_SET_VRSAVE));
18203 /* We need to clobber the registers in the mask so the scheduler
18204 does not move sets to VRSAVE before sets of AltiVec registers.
18206 However, if the function receives nonlocal gotos, reload will set
18207 all call saved registers live. We will end up with:
18209 (set (reg 999) (mem))
18210 (parallel [ (set (reg vrsave) (unspec blah))
18211 (clobber (reg 999))])
18213 The clobber will cause the store into reg 999 to be dead, and
18214 flow will attempt to delete an epilogue insn. In this case, we
18215 need an unspec use/set of the register. */
18217 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18218 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18220 if (!epiloguep || call_used_regs [i])
18221 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18222 gen_rtx_REG (V4SImode, i));
18225 rtx reg = gen_rtx_REG (V4SImode, i);
18228 = gen_rtx_SET (VOIDmode,
18230 gen_rtx_UNSPEC (V4SImode,
18231 gen_rtvec (1, reg), 27));
18235 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18237 for (i = 0; i < nclobs; ++i)
18238 XVECEXP (insn, 0, i) = clobs[i];
18243 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18244 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18247 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18248 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18250 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18251 rtx replacea, replaceb;
18253 int_rtx = GEN_INT (offset);
18255 /* Some cases that need register indexed addressing. */
18256 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18257 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18258 || (TARGET_E500_DOUBLE && mode == DFmode)
18260 && SPE_VECTOR_MODE (mode)
18261 && !SPE_CONST_OFFSET_OK (offset)))
18263 /* Whomever calls us must make sure r11 is available in the
18264 flow path of instructions in the prologue. */
18265 offset_rtx = gen_rtx_REG (Pmode, 11);
18266 emit_move_insn (offset_rtx, int_rtx);
18268 replacea = offset_rtx;
18269 replaceb = int_rtx;
18273 offset_rtx = int_rtx;
18274 replacea = NULL_RTX;
18275 replaceb = NULL_RTX;
18278 reg = gen_rtx_REG (mode, regno);
18279 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18280 mem = gen_frame_mem (mode, addr);
18282 insn = emit_move_insn (mem, reg);
18284 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18287 /* Emit an offset memory reference suitable for a frame store, while
18288 converting to a valid addressing mode. */
18291 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18293 rtx int_rtx, offset_rtx;
18295 int_rtx = GEN_INT (offset);
18297 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18298 || (TARGET_E500_DOUBLE && mode == DFmode))
18300 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18301 emit_move_insn (offset_rtx, int_rtx);
18304 offset_rtx = int_rtx;
18306 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18309 /* Look for user-defined global regs. We should not save and restore these,
18310 and cannot use stmw/lmw if there are any in its range. */
18313 no_global_regs_above (int first, bool gpr)
18316 int last = gpr ? 32 : 64;
18317 for (i = first; i < last; i++)
18318 if (global_regs[i])
18323 #ifndef TARGET_FIX_AND_CONTINUE
18324 #define TARGET_FIX_AND_CONTINUE 0
18327 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18328 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18329 #define LAST_SAVRES_REGISTER 31
18330 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18332 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18334 /* Temporary holding space for an out-of-line register save/restore
18336 static char savres_routine_name[30];
18338 /* Return the name for an out-of-line register save/restore routine.
18339 We are saving/restoring GPRs if GPR is true. */
18342 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18343 bool savep, bool gpr, bool lr)
18345 const char *prefix = "";
18346 const char *suffix = "";
18348 /* Different targets are supposed to define
18349 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18350 routine name could be defined with:
18352 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18354 This is a nice idea in practice, but in reality, things are
18355 complicated in several ways:
18357 - ELF targets have save/restore routines for GPRs.
18359 - SPE targets use different prefixes for 32/64-bit registers, and
18360 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18362 - PPC64 ELF targets have routines for save/restore of GPRs that
18363 differ in what they do with the link register, so having a set
18364 prefix doesn't work. (We only use one of the save routines at
18365 the moment, though.)
18367 - PPC32 elf targets have "exit" versions of the restore routines
18368 that restore the link register and can save some extra space.
18369 These require an extra suffix. (There are also "tail" versions
18370 of the restore routines and "GOT" versions of the save routines,
18371 but we don't generate those at present. Same problems apply,
18374 We deal with all this by synthesizing our own prefix/suffix and
18375 using that for the simple sprintf call shown above. */
18378 /* No floating point saves on the SPE. */
18382 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18384 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18389 else if (DEFAULT_ABI == ABI_V4)
18395 prefix = savep ? "_savegpr_" : "_restgpr_";
18397 prefix = savep ? "_savefpr_" : "_restfpr_";
18402 else if (DEFAULT_ABI == ABI_AIX)
18404 #ifndef POWERPC_LINUX
18405 /* No out-of-line save/restore routines for GPRs on AIX. */
18406 gcc_assert (!TARGET_AIX || !gpr);
18412 ? (lr ? "_savegpr0_" : "_savegpr1_")
18413 : (lr ? "_restgpr0_" : "_restgpr1_"));
18414 #ifdef POWERPC_LINUX
18416 prefix = (savep ? "_savefpr_" : "_restfpr_");
18420 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18421 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18424 else if (DEFAULT_ABI == ABI_DARWIN)
18425 sorry ("Out-of-line save/restore routines not supported on Darwin");
18427 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18429 return savres_routine_name;
18432 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18433 We are saving/restoring GPRs if GPR is true. */
18436 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18439 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18441 int select = ((savep ? 1 : 0) << 2
18443 /* On the SPE, we never have any FPRs, but we do have
18444 32/64-bit versions of the routines. */
18445 ? (info->spe_64bit_regs_used ? 1 : 0)
18446 : (gpr ? 1 : 0)) << 1)
18449 /* Don't generate bogus routine names. */
18450 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18451 && regno <= LAST_SAVRES_REGISTER);
18453 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18459 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18461 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18462 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18463 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18469 /* Emit a sequence of insns, including a stack tie if needed, for
18470 resetting the stack pointer. If SAVRES is true, then don't reset the
18471 stack pointer, but move the base of the frame into r11 for use by
18472 out-of-line register restore routines. */
18475 rs6000_emit_stack_reset (rs6000_stack_t *info,
18476 rtx sp_reg_rtx, rtx frame_reg_rtx,
18477 int sp_offset, bool savres)
18479 /* This blockage is needed so that sched doesn't decide to move
18480 the sp change before the register restores. */
18481 if (frame_reg_rtx != sp_reg_rtx
18483 && info->spe_64bit_regs_used != 0
18484 && info->first_gp_reg_save != 32))
18485 rs6000_emit_stack_tie ();
18487 if (frame_reg_rtx != sp_reg_rtx)
18489 if (sp_offset != 0)
18491 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18492 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18493 GEN_INT (sp_offset)));
18496 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18498 else if (sp_offset != 0)
18500 /* If we are restoring registers out-of-line, we will be using the
18501 "exit" variants of the restore routines, which will reset the
18502 stack for us. But we do need to point r11 into the right place
18503 for those routines. */
18504 rtx dest_reg = (savres
18505 ? gen_rtx_REG (Pmode, 11)
18508 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18509 GEN_INT (sp_offset)));
18516 /* Construct a parallel rtx describing the effect of a call to an
18517 out-of-line register save/restore routine. */
18520 rs6000_make_savres_rtx (rs6000_stack_t *info,
18521 rtx frame_reg_rtx, int save_area_offset,
18522 enum machine_mode reg_mode,
18523 bool savep, bool gpr, bool lr)
18526 int offset, start_reg, end_reg, n_regs;
18527 int reg_size = GET_MODE_SIZE (reg_mode);
18533 ? info->first_gp_reg_save
18534 : info->first_fp_reg_save);
18535 end_reg = gpr ? 32 : 64;
18536 n_regs = end_reg - start_reg;
18537 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18540 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18542 RTVEC_ELT (p, offset++)
18543 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18545 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18546 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18547 RTVEC_ELT (p, offset++)
18548 = gen_rtx_USE (VOIDmode,
18549 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18553 for (i = 0; i < end_reg - start_reg; i++)
18555 rtx addr, reg, mem;
18556 reg = gen_rtx_REG (reg_mode, start_reg + i);
18557 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18558 GEN_INT (save_area_offset + reg_size*i));
18559 mem = gen_frame_mem (reg_mode, addr);
18561 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18563 savep ? reg : mem);
18568 rtx addr, reg, mem;
18569 reg = gen_rtx_REG (Pmode, 0);
18570 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18571 GEN_INT (info->lr_save_offset));
18572 mem = gen_frame_mem (Pmode, addr);
18573 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18576 return gen_rtx_PARALLEL (VOIDmode, p);
18579 /* Determine whether the gp REG is really used. */
18582 rs6000_reg_live_or_pic_offset_p (int reg)
18584 return ((df_regs_ever_live_p (reg)
18585 && (!call_used_regs[reg]
18586 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18587 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18588 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18589 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18590 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18594 SAVRES_MULTIPLE = 0x1,
18595 SAVRES_INLINE_FPRS = 0x2,
18596 SAVRES_INLINE_GPRS = 0x4,
18597 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18598 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18599 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18602 /* Determine the strategy for savings/restoring registers. */
18605 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18606 int using_static_chain_p, int sibcall)
18608 bool using_multiple_p;
18610 bool savres_fprs_inline;
18611 bool savres_gprs_inline;
18612 bool noclobber_global_gprs
18613 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18616 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18617 && (!TARGET_SPE_ABI
18618 || info->spe_64bit_regs_used == 0)
18619 && info->first_gp_reg_save < 31
18620 && noclobber_global_gprs);
18621 /* Don't bother to try to save things out-of-line if r11 is occupied
18622 by the static chain. It would require too much fiddling and the
18623 static chain is rarely used anyway. */
18624 common = (using_static_chain_p
18626 || crtl->calls_eh_return
18627 || !info->lr_save_p
18628 || cfun->machine->ra_need_lr
18629 || info->total_size > 32767);
18630 savres_fprs_inline = (common
18631 || info->first_fp_reg_save == 64
18632 || !no_global_regs_above (info->first_fp_reg_save,
18634 /* The out-of-line FP routines use
18635 double-precision stores; we can't use those
18636 routines if we don't have such stores. */
18637 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18638 || FP_SAVE_INLINE (info->first_fp_reg_save));
18639 savres_gprs_inline = (common
18640 /* Saving CR interferes with the exit routines
18641 used on the SPE, so just punt here. */
18644 && info->spe_64bit_regs_used != 0
18645 && info->cr_save_p != 0)
18646 || info->first_gp_reg_save == 32
18647 || !noclobber_global_gprs
18648 || GP_SAVE_INLINE (info->first_gp_reg_save));
18651 /* If we are going to use store multiple, then don't even bother
18652 with the out-of-line routines, since the store-multiple instruction
18653 will always be smaller. */
18654 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18657 /* The situation is more complicated with load multiple. We'd
18658 prefer to use the out-of-line routines for restores, since the
18659 "exit" out-of-line routines can handle the restore of LR and
18660 the frame teardown. But we can only use the out-of-line
18661 routines if we know that we've used store multiple or
18662 out-of-line routines in the prologue, i.e. if we've saved all
18663 the registers from first_gp_reg_save. Otherwise, we risk
18664 loading garbage from the stack. Furthermore, we can only use
18665 the "exit" out-of-line gpr restore if we haven't saved any
18667 bool saved_all = !savres_gprs_inline || using_multiple_p;
18669 if (saved_all && info->first_fp_reg_save != 64)
18670 /* We can't use the exit routine; use load multiple if it's
18672 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18675 strategy = (using_multiple_p
18676 | (savres_fprs_inline << 1)
18677 | (savres_gprs_inline << 2));
18678 #ifdef POWERPC_LINUX
18681 if (!savres_fprs_inline)
18682 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18683 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18684 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18687 if (TARGET_AIX && !savres_fprs_inline)
18688 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18693 /* Emit function prologue as insns. */
18696 rs6000_emit_prologue (void)
18698 rs6000_stack_t *info = rs6000_stack_info ();
18699 enum machine_mode reg_mode = Pmode;
18700 int reg_size = TARGET_32BIT ? 4 : 8;
18701 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18702 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18703 rtx frame_reg_rtx = sp_reg_rtx;
18704 rtx cr_save_rtx = NULL_RTX;
18707 int saving_FPRs_inline;
18708 int saving_GPRs_inline;
18709 int using_store_multiple;
18710 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18711 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18712 && call_used_regs[STATIC_CHAIN_REGNUM]);
18713 HOST_WIDE_INT sp_offset = 0;
18715 if (TARGET_FIX_AND_CONTINUE)
18717 /* gdb on darwin arranges to forward a function from the old
18718 address by modifying the first 5 instructions of the function
18719 to branch to the overriding function. This is necessary to
18720 permit function pointers that point to the old function to
18721 actually forward to the new function. */
18722 emit_insn (gen_nop ());
18723 emit_insn (gen_nop ());
18724 emit_insn (gen_nop ());
18725 emit_insn (gen_nop ());
18726 emit_insn (gen_nop ());
18729 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18731 reg_mode = V2SImode;
18735 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18736 /*static_chain_p=*/using_static_chain_p,
18738 using_store_multiple = strategy & SAVRES_MULTIPLE;
18739 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18740 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18742 /* For V.4, update stack before we do any saving and set back pointer. */
18743 if (! WORLD_SAVE_P (info)
18745 && (DEFAULT_ABI == ABI_V4
18746 || crtl->calls_eh_return))
18748 bool need_r11 = (TARGET_SPE
18749 ? (!saving_GPRs_inline
18750 && info->spe_64bit_regs_used == 0)
18751 : (!saving_FPRs_inline || !saving_GPRs_inline));
18752 if (info->total_size < 32767)
18753 sp_offset = info->total_size;
18755 frame_reg_rtx = (need_r11
18756 ? gen_rtx_REG (Pmode, 11)
18758 rs6000_emit_allocate_stack (info->total_size,
18759 (frame_reg_rtx != sp_reg_rtx
18760 && (info->cr_save_p
18762 || info->first_fp_reg_save < 64
18763 || info->first_gp_reg_save < 32
18766 if (frame_reg_rtx != sp_reg_rtx)
18767 rs6000_emit_stack_tie ();
18770 /* Handle world saves specially here. */
18771 if (WORLD_SAVE_P (info))
18778 /* save_world expects lr in r0. */
18779 reg0 = gen_rtx_REG (Pmode, 0);
18780 if (info->lr_save_p)
18782 insn = emit_move_insn (reg0,
18783 gen_rtx_REG (Pmode, LR_REGNO));
18784 RTX_FRAME_RELATED_P (insn) = 1;
18787 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18788 assumptions about the offsets of various bits of the stack
18790 gcc_assert (info->gp_save_offset == -220
18791 && info->fp_save_offset == -144
18792 && info->lr_save_offset == 8
18793 && info->cr_save_offset == 4
18796 && (!crtl->calls_eh_return
18797 || info->ehrd_offset == -432)
18798 && info->vrsave_save_offset == -224
18799 && info->altivec_save_offset == -416);
18801 treg = gen_rtx_REG (SImode, 11);
18802 emit_move_insn (treg, GEN_INT (-info->total_size));
18804 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18805 in R11. It also clobbers R12, so beware! */
18807 /* Preserve CR2 for save_world prologues */
18809 sz += 32 - info->first_gp_reg_save;
18810 sz += 64 - info->first_fp_reg_save;
18811 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18812 p = rtvec_alloc (sz);
18814 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18815 gen_rtx_REG (SImode,
18817 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18818 gen_rtx_SYMBOL_REF (Pmode,
18820 /* We do floats first so that the instruction pattern matches
18822 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18824 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18825 ? DFmode : SFmode),
18826 info->first_fp_reg_save + i);
18827 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18828 GEN_INT (info->fp_save_offset
18829 + sp_offset + 8 * i));
18830 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18831 ? DFmode : SFmode), addr);
18833 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18835 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18837 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18838 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18839 GEN_INT (info->altivec_save_offset
18840 + sp_offset + 16 * i));
18841 rtx mem = gen_frame_mem (V4SImode, addr);
18843 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18845 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18847 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18848 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18849 GEN_INT (info->gp_save_offset
18850 + sp_offset + reg_size * i));
18851 rtx mem = gen_frame_mem (reg_mode, addr);
18853 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18857 /* CR register traditionally saved as CR2. */
18858 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18859 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18860 GEN_INT (info->cr_save_offset
18862 rtx mem = gen_frame_mem (reg_mode, addr);
18864 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18866 /* Explain about use of R0. */
18867 if (info->lr_save_p)
18869 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18870 GEN_INT (info->lr_save_offset
18872 rtx mem = gen_frame_mem (reg_mode, addr);
18874 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18876 /* Explain what happens to the stack pointer. */
18878 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18879 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18882 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18883 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18884 treg, GEN_INT (-info->total_size));
18885 sp_offset = info->total_size;
18888 /* If we use the link register, get it into r0. */
18889 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18891 rtx addr, reg, mem;
18893 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18894 gen_rtx_REG (Pmode, LR_REGNO));
18895 RTX_FRAME_RELATED_P (insn) = 1;
18897 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18898 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18900 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18901 GEN_INT (info->lr_save_offset + sp_offset));
18902 reg = gen_rtx_REG (Pmode, 0);
18903 mem = gen_rtx_MEM (Pmode, addr);
18904 /* This should not be of rs6000_sr_alias_set, because of
18905 __builtin_return_address. */
18907 insn = emit_move_insn (mem, reg);
18908 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18909 NULL_RTX, NULL_RTX);
18913 /* If we need to save CR, put it into r12 or r11. */
18914 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18919 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18921 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18922 RTX_FRAME_RELATED_P (insn) = 1;
18923 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18924 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18925 But that's OK. All we have to do is specify that _one_ condition
18926 code register is saved in this stack slot. The thrower's epilogue
18927 will then restore all the call-saved registers.
18928 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18929 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18930 gen_rtx_REG (SImode, CR2_REGNO));
18931 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18934 /* Do any required saving of fpr's. If only one or two to save, do
18935 it ourselves. Otherwise, call function. */
18936 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18939 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18940 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18941 && ! call_used_regs[info->first_fp_reg_save+i]))
18942 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18943 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18945 info->first_fp_reg_save + i,
18946 info->fp_save_offset + sp_offset + 8 * i,
18949 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18953 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18954 info->fp_save_offset + sp_offset,
18956 /*savep=*/true, /*gpr=*/false,
18958 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18960 insn = emit_insn (par);
18961 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18962 NULL_RTX, NULL_RTX);
18965 /* Save GPRs. This is done as a PARALLEL if we are using
18966 the store-multiple instructions. */
18967 if (!WORLD_SAVE_P (info)
18969 && info->spe_64bit_regs_used != 0
18970 && info->first_gp_reg_save != 32)
18973 rtx spe_save_area_ptr;
18975 /* Determine whether we can address all of the registers that need
18976 to be saved with an offset from the stack pointer that fits in
18977 the small const field for SPE memory instructions. */
18978 int spe_regs_addressable_via_sp
18979 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18980 + (32 - info->first_gp_reg_save - 1) * reg_size)
18981 && saving_GPRs_inline);
18984 if (spe_regs_addressable_via_sp)
18986 spe_save_area_ptr = frame_reg_rtx;
18987 spe_offset = info->spe_gp_save_offset + sp_offset;
18991 /* Make r11 point to the start of the SPE save area. We need
18992 to be careful here if r11 is holding the static chain. If
18993 it is, then temporarily save it in r0. We would use r0 as
18994 our base register here, but using r0 as a base register in
18995 loads and stores means something different from what we
18997 int ool_adjust = (saving_GPRs_inline
18999 : (info->first_gp_reg_save
19000 - (FIRST_SAVRES_REGISTER+1))*8);
19001 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19002 + sp_offset - ool_adjust);
19004 if (using_static_chain_p)
19006 rtx r0 = gen_rtx_REG (Pmode, 0);
19007 gcc_assert (info->first_gp_reg_save > 11);
19009 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19012 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19013 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19015 GEN_INT (offset)));
19016 /* We need to make sure the move to r11 gets noted for
19017 properly outputting unwind information. */
19018 if (!saving_GPRs_inline)
19019 rs6000_frame_related (insn, frame_reg_rtx, offset,
19020 NULL_RTX, NULL_RTX);
19024 if (saving_GPRs_inline)
19026 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19027 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19029 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19030 rtx offset, addr, mem;
19032 /* We're doing all this to ensure that the offset fits into
19033 the immediate offset of 'evstdd'. */
19034 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19036 offset = GEN_INT (reg_size * i + spe_offset);
19037 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19038 mem = gen_rtx_MEM (V2SImode, addr);
19040 insn = emit_move_insn (mem, reg);
19042 rs6000_frame_related (insn, spe_save_area_ptr,
19043 info->spe_gp_save_offset
19044 + sp_offset + reg_size * i,
19045 offset, const0_rtx);
19052 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19054 /*savep=*/true, /*gpr=*/true,
19056 insn = emit_insn (par);
19057 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19058 NULL_RTX, NULL_RTX);
19062 /* Move the static chain pointer back. */
19063 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19064 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19066 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19070 /* Need to adjust r11 (r12) if we saved any FPRs. */
19071 if (info->first_fp_reg_save != 64)
19073 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19075 rtx offset = GEN_INT (sp_offset
19076 + (-8 * (64-info->first_fp_reg_save)));
19077 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19080 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19081 info->gp_save_offset + sp_offset,
19083 /*savep=*/true, /*gpr=*/true,
19085 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19087 insn = emit_insn (par);
19088 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19089 NULL_RTX, NULL_RTX);
19091 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19095 p = rtvec_alloc (32 - info->first_gp_reg_save);
19096 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19098 rtx addr, reg, mem;
19099 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19100 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19101 GEN_INT (info->gp_save_offset
19104 mem = gen_frame_mem (reg_mode, addr);
19106 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19108 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19109 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19110 NULL_RTX, NULL_RTX);
19112 else if (!WORLD_SAVE_P (info))
19115 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19116 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19118 rtx addr, reg, mem;
19119 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19121 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19122 GEN_INT (info->gp_save_offset
19125 mem = gen_frame_mem (reg_mode, addr);
19127 insn = emit_move_insn (mem, reg);
19128 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19129 NULL_RTX, NULL_RTX);
19133 /* ??? There's no need to emit actual instructions here, but it's the
19134 easiest way to get the frame unwind information emitted. */
19135 if (crtl->calls_eh_return)
19137 unsigned int i, regno;
19139 /* In AIX ABI we need to pretend we save r2 here. */
19142 rtx addr, reg, mem;
19144 reg = gen_rtx_REG (reg_mode, 2);
19145 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19146 GEN_INT (sp_offset + 5 * reg_size));
19147 mem = gen_frame_mem (reg_mode, addr);
19149 insn = emit_move_insn (mem, reg);
19150 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19151 NULL_RTX, NULL_RTX);
19152 PATTERN (insn) = gen_blockage ();
19157 regno = EH_RETURN_DATA_REGNO (i);
19158 if (regno == INVALID_REGNUM)
19161 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19162 info->ehrd_offset + sp_offset
19163 + reg_size * (int) i,
19168 /* Save CR if we use any that must be preserved. */
19169 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19171 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19172 GEN_INT (info->cr_save_offset + sp_offset));
19173 rtx mem = gen_frame_mem (SImode, addr);
19174 /* See the large comment above about why CR2_REGNO is used. */
19175 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19177 /* If r12 was used to hold the original sp, copy cr into r0 now
19179 if (REGNO (frame_reg_rtx) == 12)
19183 cr_save_rtx = gen_rtx_REG (SImode, 0);
19184 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19185 RTX_FRAME_RELATED_P (insn) = 1;
19186 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19187 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19189 insn = emit_move_insn (mem, cr_save_rtx);
19191 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19192 NULL_RTX, NULL_RTX);
19195 /* Update stack and set back pointer unless this is V.4,
19196 for which it was done previously. */
19197 if (!WORLD_SAVE_P (info) && info->push_p
19198 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19200 if (info->total_size < 32767)
19201 sp_offset = info->total_size;
19203 frame_reg_rtx = frame_ptr_rtx;
19204 rs6000_emit_allocate_stack (info->total_size,
19205 (frame_reg_rtx != sp_reg_rtx
19206 && ((info->altivec_size != 0)
19207 || (info->vrsave_mask != 0)
19210 if (frame_reg_rtx != sp_reg_rtx)
19211 rs6000_emit_stack_tie ();
19214 /* Set frame pointer, if needed. */
19215 if (frame_pointer_needed)
19217 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19219 RTX_FRAME_RELATED_P (insn) = 1;
19222 /* Save AltiVec registers if needed. Save here because the red zone does
19223 not include AltiVec registers. */
19224 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19228 /* There should be a non inline version of this, for when we
19229 are saving lots of vector registers. */
19230 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19231 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19233 rtx areg, savereg, mem;
19236 offset = info->altivec_save_offset + sp_offset
19237 + 16 * (i - info->first_altivec_reg_save);
19239 savereg = gen_rtx_REG (V4SImode, i);
19241 areg = gen_rtx_REG (Pmode, 0);
19242 emit_move_insn (areg, GEN_INT (offset));
19244 /* AltiVec addressing mode is [reg+reg]. */
19245 mem = gen_frame_mem (V4SImode,
19246 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19248 insn = emit_move_insn (mem, savereg);
19250 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19251 areg, GEN_INT (offset));
19255 /* VRSAVE is a bit vector representing which AltiVec registers
19256 are used. The OS uses this to determine which vector
19257 registers to save on a context switch. We need to save
19258 VRSAVE on the stack frame, add whatever AltiVec registers we
19259 used in this function, and do the corresponding magic in the
19262 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19263 && info->vrsave_mask != 0)
19265 rtx reg, mem, vrsave;
19268 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19269 as frame_reg_rtx and r11 as the static chain pointer for
19270 nested functions. */
19271 reg = gen_rtx_REG (SImode, 0);
19272 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19274 emit_insn (gen_get_vrsave_internal (reg));
19276 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19278 if (!WORLD_SAVE_P (info))
19281 offset = info->vrsave_save_offset + sp_offset;
19282 mem = gen_frame_mem (SImode,
19283 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19284 GEN_INT (offset)));
19285 insn = emit_move_insn (mem, reg);
19288 /* Include the registers in the mask. */
19289 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19291 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19294 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19295 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19296 || (DEFAULT_ABI == ABI_V4
19297 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19298 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19300 /* If emit_load_toc_table will use the link register, we need to save
19301 it. We use R12 for this purpose because emit_load_toc_table
19302 can use register 0. This allows us to use a plain 'blr' to return
19303 from the procedure more often. */
19304 int save_LR_around_toc_setup = (TARGET_ELF
19305 && DEFAULT_ABI != ABI_AIX
19307 && ! info->lr_save_p
19308 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19309 if (save_LR_around_toc_setup)
19311 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19313 insn = emit_move_insn (frame_ptr_rtx, lr);
19314 RTX_FRAME_RELATED_P (insn) = 1;
19316 rs6000_emit_load_toc_table (TRUE);
19318 insn = emit_move_insn (lr, frame_ptr_rtx);
19319 RTX_FRAME_RELATED_P (insn) = 1;
19322 rs6000_emit_load_toc_table (TRUE);
19326 if (DEFAULT_ABI == ABI_DARWIN
19327 && flag_pic && crtl->uses_pic_offset_table)
19329 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19330 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19332 /* Save and restore LR locally around this call (in R0). */
19333 if (!info->lr_save_p)
19334 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19336 emit_insn (gen_load_macho_picbase (src));
19338 emit_move_insn (gen_rtx_REG (Pmode,
19339 RS6000_PIC_OFFSET_TABLE_REGNUM),
19342 if (!info->lr_save_p)
19343 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19348 /* Write function prologue. */
19351 rs6000_output_function_prologue (FILE *file,
19352 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19354 rs6000_stack_t *info = rs6000_stack_info ();
19356 if (TARGET_DEBUG_STACK)
19357 debug_stack_info (info);
19359 /* Write .extern for any function we will call to save and restore
19361 if (info->first_fp_reg_save < 64
19362 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19365 int regno = info->first_fp_reg_save - 32;
19367 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19368 /*gpr=*/false, /*lr=*/false);
19369 fprintf (file, "\t.extern %s\n", name);
19371 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19372 /*gpr=*/false, /*lr=*/true);
19373 fprintf (file, "\t.extern %s\n", name);
19376 /* Write .extern for AIX common mode routines, if needed. */
19377 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19379 fputs ("\t.extern __mulh\n", file);
19380 fputs ("\t.extern __mull\n", file);
19381 fputs ("\t.extern __divss\n", file);
19382 fputs ("\t.extern __divus\n", file);
19383 fputs ("\t.extern __quoss\n", file);
19384 fputs ("\t.extern __quous\n", file);
19385 common_mode_defined = 1;
19388 if (! HAVE_prologue)
19394 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19395 the "toplevel" insn chain. */
19396 emit_note (NOTE_INSN_DELETED);
19397 rs6000_emit_prologue ();
19398 emit_note (NOTE_INSN_DELETED);
19400 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19404 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19406 INSN_ADDRESSES_NEW (insn, addr);
19411 prologue = get_insns ();
19414 if (TARGET_DEBUG_STACK)
19415 debug_rtx_list (prologue, 100);
19417 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19421 rs6000_pic_labelno++;
19424 /* Non-zero if vmx regs are restored before the frame pop, zero if
19425 we restore after the pop when possible. */
19426 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19428 /* Reload CR from REG. */
19431 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19436 if (using_mfcr_multiple)
19438 for (i = 0; i < 8; i++)
19439 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19441 gcc_assert (count);
19444 if (using_mfcr_multiple && count > 1)
19449 p = rtvec_alloc (count);
19452 for (i = 0; i < 8; i++)
19453 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19455 rtvec r = rtvec_alloc (2);
19456 RTVEC_ELT (r, 0) = reg;
19457 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19458 RTVEC_ELT (p, ndx) =
19459 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19460 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19463 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19464 gcc_assert (ndx == count);
19467 for (i = 0; i < 8; i++)
19468 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19470 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19476 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19477 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19478 below stack pointer not cloberred by signals. */
19481 offset_below_red_zone_p (HOST_WIDE_INT offset)
19483 return offset < (DEFAULT_ABI == ABI_V4
19485 : TARGET_32BIT ? -220 : -288);
19488 /* Emit function epilogue as insns. */
19491 rs6000_emit_epilogue (int sibcall)
19493 rs6000_stack_t *info;
19494 int restoring_GPRs_inline;
19495 int restoring_FPRs_inline;
19496 int using_load_multiple;
19497 int using_mtcr_multiple;
19498 int use_backchain_to_restore_sp;
19502 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19503 rtx frame_reg_rtx = sp_reg_rtx;
19504 rtx cfa_restores = NULL_RTX;
19506 rtx cr_save_reg = NULL_RTX;
19507 enum machine_mode reg_mode = Pmode;
19508 int reg_size = TARGET_32BIT ? 4 : 8;
19511 info = rs6000_stack_info ();
19513 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19515 reg_mode = V2SImode;
19519 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19520 /*static_chain_p=*/0, sibcall);
19521 using_load_multiple = strategy & SAVRES_MULTIPLE;
19522 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19523 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19524 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19525 || rs6000_cpu == PROCESSOR_PPC603
19526 || rs6000_cpu == PROCESSOR_PPC750
19528 /* Restore via the backchain when we have a large frame, since this
19529 is more efficient than an addis, addi pair. The second condition
19530 here will not trigger at the moment; We don't actually need a
19531 frame pointer for alloca, but the generic parts of the compiler
19532 give us one anyway. */
19533 use_backchain_to_restore_sp = (info->total_size > 32767
19534 || info->total_size
19535 + (info->lr_save_p ? info->lr_save_offset : 0)
19537 || (cfun->calls_alloca
19538 && !frame_pointer_needed));
19539 restore_lr = (info->lr_save_p
19540 && (restoring_FPRs_inline
19541 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19542 && (restoring_GPRs_inline
19543 || info->first_fp_reg_save < 64));
19545 if (WORLD_SAVE_P (info))
19549 const char *alloc_rname;
19552 /* eh_rest_world_r10 will return to the location saved in the LR
19553 stack slot (which is not likely to be our caller.)
19554 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19555 rest_world is similar, except any R10 parameter is ignored.
19556 The exception-handling stuff that was here in 2.95 is no
19557 longer necessary. */
19561 + 32 - info->first_gp_reg_save
19562 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19563 + 63 + 1 - info->first_fp_reg_save);
19565 strcpy (rname, ((crtl->calls_eh_return) ?
19566 "*eh_rest_world_r10" : "*rest_world"));
19567 alloc_rname = ggc_strdup (rname);
19570 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19571 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19572 gen_rtx_REG (Pmode,
19575 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19576 /* The instruction pattern requires a clobber here;
19577 it is shared with the restVEC helper. */
19579 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19582 /* CR register traditionally saved as CR2. */
19583 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19584 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19585 GEN_INT (info->cr_save_offset));
19586 rtx mem = gen_frame_mem (reg_mode, addr);
19588 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19591 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19593 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19594 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19595 GEN_INT (info->gp_save_offset
19597 rtx mem = gen_frame_mem (reg_mode, addr);
19599 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19601 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19603 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19604 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19605 GEN_INT (info->altivec_save_offset
19607 rtx mem = gen_frame_mem (V4SImode, addr);
19609 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19611 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19613 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19614 ? DFmode : SFmode),
19615 info->first_fp_reg_save + i);
19616 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19617 GEN_INT (info->fp_save_offset
19619 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19620 ? DFmode : SFmode), addr);
19622 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19625 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19627 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19629 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19631 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19633 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19634 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19639 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19641 sp_offset = info->total_size;
19643 /* Restore AltiVec registers if we must do so before adjusting the
19645 if (TARGET_ALTIVEC_ABI
19646 && info->altivec_size != 0
19647 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19648 || (DEFAULT_ABI != ABI_V4
19649 && offset_below_red_zone_p (info->altivec_save_offset))))
19653 if (use_backchain_to_restore_sp)
19655 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19656 emit_move_insn (frame_reg_rtx,
19657 gen_rtx_MEM (Pmode, sp_reg_rtx));
19660 else if (frame_pointer_needed)
19661 frame_reg_rtx = hard_frame_pointer_rtx;
19663 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19664 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19666 rtx addr, areg, mem, reg;
19668 areg = gen_rtx_REG (Pmode, 0);
19670 (areg, GEN_INT (info->altivec_save_offset
19672 + 16 * (i - info->first_altivec_reg_save)));
19674 /* AltiVec addressing mode is [reg+reg]. */
19675 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19676 mem = gen_frame_mem (V4SImode, addr);
19678 reg = gen_rtx_REG (V4SImode, i);
19679 emit_move_insn (reg, mem);
19680 if (offset_below_red_zone_p (info->altivec_save_offset
19681 + (i - info->first_altivec_reg_save)
19683 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19688 /* Restore VRSAVE if we must do so before adjusting the stack. */
19690 && TARGET_ALTIVEC_VRSAVE
19691 && info->vrsave_mask != 0
19692 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19693 || (DEFAULT_ABI != ABI_V4
19694 && offset_below_red_zone_p (info->vrsave_save_offset))))
19696 rtx addr, mem, reg;
19698 if (frame_reg_rtx == sp_reg_rtx)
19700 if (use_backchain_to_restore_sp)
19702 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19703 emit_move_insn (frame_reg_rtx,
19704 gen_rtx_MEM (Pmode, sp_reg_rtx));
19707 else if (frame_pointer_needed)
19708 frame_reg_rtx = hard_frame_pointer_rtx;
19711 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19712 GEN_INT (info->vrsave_save_offset + sp_offset));
19713 mem = gen_frame_mem (SImode, addr);
19714 reg = gen_rtx_REG (SImode, 12);
19715 emit_move_insn (reg, mem);
19717 emit_insn (generate_set_vrsave (reg, info, 1));
19721 /* If we have a large stack frame, restore the old stack pointer
19722 using the backchain. */
19723 if (use_backchain_to_restore_sp)
19725 if (frame_reg_rtx == sp_reg_rtx)
19727 /* Under V.4, don't reset the stack pointer until after we're done
19728 loading the saved registers. */
19729 if (DEFAULT_ABI == ABI_V4)
19730 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19732 insn = emit_move_insn (frame_reg_rtx,
19733 gen_rtx_MEM (Pmode, sp_reg_rtx));
19736 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19737 && DEFAULT_ABI == ABI_V4)
19738 /* frame_reg_rtx has been set up by the altivec restore. */
19742 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19743 frame_reg_rtx = sp_reg_rtx;
19746 /* If we have a frame pointer, we can restore the old stack pointer
19748 else if (frame_pointer_needed)
19750 frame_reg_rtx = sp_reg_rtx;
19751 if (DEFAULT_ABI == ABI_V4)
19752 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19754 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19755 GEN_INT (info->total_size)));
19758 else if (info->push_p
19759 && DEFAULT_ABI != ABI_V4
19760 && !crtl->calls_eh_return)
19762 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19763 GEN_INT (info->total_size)));
19766 if (insn && frame_reg_rtx == sp_reg_rtx)
19770 REG_NOTES (insn) = cfa_restores;
19771 cfa_restores = NULL_RTX;
19773 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19774 RTX_FRAME_RELATED_P (insn) = 1;
19777 /* Restore AltiVec registers if we have not done so already. */
19778 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19779 && TARGET_ALTIVEC_ABI
19780 && info->altivec_size != 0
19781 && (DEFAULT_ABI == ABI_V4
19782 || !offset_below_red_zone_p (info->altivec_save_offset)))
19786 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19787 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19789 rtx addr, areg, mem, reg;
19791 areg = gen_rtx_REG (Pmode, 0);
19793 (areg, GEN_INT (info->altivec_save_offset
19795 + 16 * (i - info->first_altivec_reg_save)));
19797 /* AltiVec addressing mode is [reg+reg]. */
19798 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19799 mem = gen_frame_mem (V4SImode, addr);
19801 reg = gen_rtx_REG (V4SImode, i);
19802 emit_move_insn (reg, mem);
19803 if (DEFAULT_ABI == ABI_V4)
19804 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19809 /* Restore VRSAVE if we have not done so already. */
19810 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19812 && TARGET_ALTIVEC_VRSAVE
19813 && info->vrsave_mask != 0
19814 && (DEFAULT_ABI == ABI_V4
19815 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19817 rtx addr, mem, reg;
19819 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19820 GEN_INT (info->vrsave_save_offset + sp_offset));
19821 mem = gen_frame_mem (SImode, addr);
19822 reg = gen_rtx_REG (SImode, 12);
19823 emit_move_insn (reg, mem);
19825 emit_insn (generate_set_vrsave (reg, info, 1));
19828 /* Get the old lr if we saved it. If we are restoring registers
19829 out-of-line, then the out-of-line routines can do this for us. */
19830 if (restore_lr && restoring_GPRs_inline)
19832 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19833 info->lr_save_offset + sp_offset);
19835 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19838 /* Get the old cr if we saved it. */
19839 if (info->cr_save_p)
19841 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19842 GEN_INT (info->cr_save_offset + sp_offset));
19843 rtx mem = gen_frame_mem (SImode, addr);
19845 cr_save_reg = gen_rtx_REG (SImode,
19846 DEFAULT_ABI == ABI_AIX
19847 && !restoring_GPRs_inline
19848 && info->first_fp_reg_save < 64
19850 emit_move_insn (cr_save_reg, mem);
19853 /* Set LR here to try to overlap restores below. LR is always saved
19854 above incoming stack, so it never needs REG_CFA_RESTORE. */
19855 if (restore_lr && restoring_GPRs_inline)
19856 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19857 gen_rtx_REG (Pmode, 0));
19859 /* Load exception handler data registers, if needed. */
19860 if (crtl->calls_eh_return)
19862 unsigned int i, regno;
19866 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19867 GEN_INT (sp_offset + 5 * reg_size));
19868 rtx mem = gen_frame_mem (reg_mode, addr);
19870 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19877 regno = EH_RETURN_DATA_REGNO (i);
19878 if (regno == INVALID_REGNUM)
19881 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19882 info->ehrd_offset + sp_offset
19883 + reg_size * (int) i);
19885 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19889 /* Restore GPRs. This is done as a PARALLEL if we are using
19890 the load-multiple instructions. */
19892 && info->spe_64bit_regs_used != 0
19893 && info->first_gp_reg_save != 32)
19895 /* Determine whether we can address all of the registers that need
19896 to be saved with an offset from the stack pointer that fits in
19897 the small const field for SPE memory instructions. */
19898 int spe_regs_addressable_via_sp
19899 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19900 + (32 - info->first_gp_reg_save - 1) * reg_size)
19901 && restoring_GPRs_inline);
19904 if (spe_regs_addressable_via_sp)
19905 spe_offset = info->spe_gp_save_offset + sp_offset;
19908 rtx old_frame_reg_rtx = frame_reg_rtx;
19909 /* Make r11 point to the start of the SPE save area. We worried about
19910 not clobbering it when we were saving registers in the prologue.
19911 There's no need to worry here because the static chain is passed
19912 anew to every function. */
19913 int ool_adjust = (restoring_GPRs_inline
19915 : (info->first_gp_reg_save
19916 - (FIRST_SAVRES_REGISTER+1))*8);
19918 if (frame_reg_rtx == sp_reg_rtx)
19919 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19920 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19921 GEN_INT (info->spe_gp_save_offset
19924 /* Keep the invariant that frame_reg_rtx + sp_offset points
19925 at the top of the stack frame. */
19926 sp_offset = -info->spe_gp_save_offset;
19931 if (restoring_GPRs_inline)
19933 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19934 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19936 rtx offset, addr, mem, reg;
19938 /* We're doing all this to ensure that the immediate offset
19939 fits into the immediate field of 'evldd'. */
19940 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19942 offset = GEN_INT (spe_offset + reg_size * i);
19943 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19944 mem = gen_rtx_MEM (V2SImode, addr);
19945 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19947 insn = emit_move_insn (reg, mem);
19948 if (DEFAULT_ABI == ABI_V4)
19950 if (frame_pointer_needed
19951 && info->first_gp_reg_save + i
19952 == HARD_FRAME_POINTER_REGNUM)
19954 add_reg_note (insn, REG_CFA_DEF_CFA,
19955 plus_constant (frame_reg_rtx,
19957 RTX_FRAME_RELATED_P (insn) = 1;
19960 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19969 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19971 /*savep=*/false, /*gpr=*/true,
19973 emit_jump_insn (par);
19974 /* We don't want anybody else emitting things after we jumped
19979 else if (!restoring_GPRs_inline)
19981 /* We are jumping to an out-of-line function. */
19982 bool can_use_exit = info->first_fp_reg_save == 64;
19985 /* Emit stack reset code if we need it. */
19987 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19988 sp_offset, can_use_exit);
19991 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19994 GEN_INT (sp_offset - info->fp_size)));
19995 if (REGNO (frame_reg_rtx) == 11)
19996 sp_offset += info->fp_size;
19999 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20000 info->gp_save_offset, reg_mode,
20001 /*savep=*/false, /*gpr=*/true,
20002 /*lr=*/can_use_exit);
20006 if (info->cr_save_p)
20008 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20009 if (DEFAULT_ABI == ABI_V4)
20011 = alloc_reg_note (REG_CFA_RESTORE,
20012 gen_rtx_REG (SImode, CR2_REGNO),
20016 emit_jump_insn (par);
20018 /* We don't want anybody else emitting things after we jumped
20023 insn = emit_insn (par);
20024 if (DEFAULT_ABI == ABI_V4)
20026 if (frame_pointer_needed)
20028 add_reg_note (insn, REG_CFA_DEF_CFA,
20029 plus_constant (frame_reg_rtx, sp_offset));
20030 RTX_FRAME_RELATED_P (insn) = 1;
20033 for (i = info->first_gp_reg_save; i < 32; i++)
20035 = alloc_reg_note (REG_CFA_RESTORE,
20036 gen_rtx_REG (reg_mode, i), cfa_restores);
20039 else if (using_load_multiple)
20042 p = rtvec_alloc (32 - info->first_gp_reg_save);
20043 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20045 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20046 GEN_INT (info->gp_save_offset
20049 rtx mem = gen_frame_mem (reg_mode, addr);
20050 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20052 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20053 if (DEFAULT_ABI == ABI_V4)
20054 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20057 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20058 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20060 add_reg_note (insn, REG_CFA_DEF_CFA,
20061 plus_constant (frame_reg_rtx, sp_offset));
20062 RTX_FRAME_RELATED_P (insn) = 1;
20067 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20068 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20070 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20071 GEN_INT (info->gp_save_offset
20074 rtx mem = gen_frame_mem (reg_mode, addr);
20075 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20077 insn = emit_move_insn (reg, mem);
20078 if (DEFAULT_ABI == ABI_V4)
20080 if (frame_pointer_needed
20081 && info->first_gp_reg_save + i
20082 == HARD_FRAME_POINTER_REGNUM)
20084 add_reg_note (insn, REG_CFA_DEF_CFA,
20085 plus_constant (frame_reg_rtx, sp_offset));
20086 RTX_FRAME_RELATED_P (insn) = 1;
20089 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20095 if (restore_lr && !restoring_GPRs_inline)
20097 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20098 info->lr_save_offset + sp_offset);
20100 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20101 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20102 gen_rtx_REG (Pmode, 0));
20105 /* Restore fpr's if we need to do it without calling a function. */
20106 if (restoring_FPRs_inline)
20107 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20108 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20109 && ! call_used_regs[info->first_fp_reg_save+i]))
20111 rtx addr, mem, reg;
20112 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20113 GEN_INT (info->fp_save_offset
20116 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20117 ? DFmode : SFmode), addr);
20118 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20119 ? DFmode : SFmode),
20120 info->first_fp_reg_save + i);
20122 emit_move_insn (reg, mem);
20123 if (DEFAULT_ABI == ABI_V4)
20124 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20128 /* If we saved cr, restore it here. Just those that were used. */
20129 if (info->cr_save_p)
20131 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20132 if (DEFAULT_ABI == ABI_V4)
20134 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20138 /* If this is V.4, unwind the stack pointer after all of the loads
20140 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20141 sp_offset, !restoring_FPRs_inline);
20146 REG_NOTES (insn) = cfa_restores;
20147 cfa_restores = NULL_RTX;
20149 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20150 RTX_FRAME_RELATED_P (insn) = 1;
20153 if (crtl->calls_eh_return)
20155 rtx sa = EH_RETURN_STACKADJ_RTX;
20156 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20162 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20163 if (! restoring_FPRs_inline)
20164 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20166 p = rtvec_alloc (2);
20168 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20169 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20170 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20171 : gen_rtx_CLOBBER (VOIDmode,
20172 gen_rtx_REG (Pmode, 65)));
20174 /* If we have to restore more than two FP registers, branch to the
20175 restore function. It will return to our caller. */
20176 if (! restoring_FPRs_inline)
20181 sym = rs6000_savres_routine_sym (info,
20185 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20186 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20187 gen_rtx_REG (Pmode,
20188 DEFAULT_ABI == ABI_AIX
20190 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20193 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20194 GEN_INT (info->fp_save_offset + 8*i));
20195 mem = gen_frame_mem (DFmode, addr);
20197 RTVEC_ELT (p, i+4) =
20198 gen_rtx_SET (VOIDmode,
20199 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20204 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20208 /* Write function epilogue. */
20211 rs6000_output_function_epilogue (FILE *file,
20212 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20214 if (! HAVE_epilogue)
20216 rtx insn = get_last_insn ();
20217 /* If the last insn was a BARRIER, we don't have to write anything except
20218 the trace table. */
20219 if (GET_CODE (insn) == NOTE)
20220 insn = prev_nonnote_insn (insn);
20221 if (insn == 0 || GET_CODE (insn) != BARRIER)
20223 /* This is slightly ugly, but at least we don't have two
20224 copies of the epilogue-emitting code. */
20227 /* A NOTE_INSN_DELETED is supposed to be at the start
20228 and end of the "toplevel" insn chain. */
20229 emit_note (NOTE_INSN_DELETED);
20230 rs6000_emit_epilogue (FALSE);
20231 emit_note (NOTE_INSN_DELETED);
20233 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20237 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20239 INSN_ADDRESSES_NEW (insn, addr);
20244 if (TARGET_DEBUG_STACK)
20245 debug_rtx_list (get_insns (), 100);
20246 final (get_insns (), file, FALSE);
20252 macho_branch_islands ();
20253 /* Mach-O doesn't support labels at the end of objects, so if
20254 it looks like we might want one, insert a NOP. */
20256 rtx insn = get_last_insn ();
20259 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20260 insn = PREV_INSN (insn);
20264 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20265 fputs ("\tnop\n", file);
20269 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20272 We don't output a traceback table if -finhibit-size-directive was
20273 used. The documentation for -finhibit-size-directive reads
20274 ``don't output a @code{.size} assembler directive, or anything
20275 else that would cause trouble if the function is split in the
20276 middle, and the two halves are placed at locations far apart in
20277 memory.'' The traceback table has this property, since it
20278 includes the offset from the start of the function to the
20279 traceback table itself.
20281 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20282 different traceback table. */
20283 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20284 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20286 const char *fname = NULL;
20287 const char *language_string = lang_hooks.name;
20288 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20290 int optional_tbtab;
20291 rs6000_stack_t *info = rs6000_stack_info ();
20293 if (rs6000_traceback == traceback_full)
20294 optional_tbtab = 1;
20295 else if (rs6000_traceback == traceback_part)
20296 optional_tbtab = 0;
20298 optional_tbtab = !optimize_size && !TARGET_ELF;
20300 if (optional_tbtab)
20302 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20303 while (*fname == '.') /* V.4 encodes . in the name */
20306 /* Need label immediately before tbtab, so we can compute
20307 its offset from the function start. */
20308 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20309 ASM_OUTPUT_LABEL (file, fname);
20312 /* The .tbtab pseudo-op can only be used for the first eight
20313 expressions, since it can't handle the possibly variable
20314 length fields that follow. However, if you omit the optional
20315 fields, the assembler outputs zeros for all optional fields
20316 anyways, giving each variable length field is minimum length
20317 (as defined in sys/debug.h). Thus we can not use the .tbtab
20318 pseudo-op at all. */
20320 /* An all-zero word flags the start of the tbtab, for debuggers
20321 that have to find it by searching forward from the entry
20322 point or from the current pc. */
20323 fputs ("\t.long 0\n", file);
20325 /* Tbtab format type. Use format type 0. */
20326 fputs ("\t.byte 0,", file);
20328 /* Language type. Unfortunately, there does not seem to be any
20329 official way to discover the language being compiled, so we
20330 use language_string.
20331 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20332 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20333 a number, so for now use 9. LTO isn't assigned a number either,
20334 so for now use 0. */
20335 if (! strcmp (language_string, "GNU C")
20336 || ! strcmp (language_string, "GNU GIMPLE"))
20338 else if (! strcmp (language_string, "GNU F77")
20339 || ! strcmp (language_string, "GNU Fortran"))
20341 else if (! strcmp (language_string, "GNU Pascal"))
20343 else if (! strcmp (language_string, "GNU Ada"))
20345 else if (! strcmp (language_string, "GNU C++")
20346 || ! strcmp (language_string, "GNU Objective-C++"))
20348 else if (! strcmp (language_string, "GNU Java"))
20350 else if (! strcmp (language_string, "GNU Objective-C"))
20353 gcc_unreachable ();
20354 fprintf (file, "%d,", i);
20356 /* 8 single bit fields: global linkage (not set for C extern linkage,
20357 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20358 from start of procedure stored in tbtab, internal function, function
20359 has controlled storage, function has no toc, function uses fp,
20360 function logs/aborts fp operations. */
20361 /* Assume that fp operations are used if any fp reg must be saved. */
20362 fprintf (file, "%d,",
20363 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20365 /* 6 bitfields: function is interrupt handler, name present in
20366 proc table, function calls alloca, on condition directives
20367 (controls stack walks, 3 bits), saves condition reg, saves
20369 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20370 set up as a frame pointer, even when there is no alloca call. */
20371 fprintf (file, "%d,",
20372 ((optional_tbtab << 6)
20373 | ((optional_tbtab & frame_pointer_needed) << 5)
20374 | (info->cr_save_p << 1)
20375 | (info->lr_save_p)));
20377 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20379 fprintf (file, "%d,",
20380 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20382 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20383 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20385 if (optional_tbtab)
20387 /* Compute the parameter info from the function decl argument
20390 int next_parm_info_bit = 31;
20392 for (decl = DECL_ARGUMENTS (current_function_decl);
20393 decl; decl = TREE_CHAIN (decl))
20395 rtx parameter = DECL_INCOMING_RTL (decl);
20396 enum machine_mode mode = GET_MODE (parameter);
20398 if (GET_CODE (parameter) == REG)
20400 if (SCALAR_FLOAT_MODE_P (mode))
20421 gcc_unreachable ();
20424 /* If only one bit will fit, don't or in this entry. */
20425 if (next_parm_info_bit > 0)
20426 parm_info |= (bits << (next_parm_info_bit - 1));
20427 next_parm_info_bit -= 2;
20431 fixed_parms += ((GET_MODE_SIZE (mode)
20432 + (UNITS_PER_WORD - 1))
20434 next_parm_info_bit -= 1;
20440 /* Number of fixed point parameters. */
20441 /* This is actually the number of words of fixed point parameters; thus
20442 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20443 fprintf (file, "%d,", fixed_parms);
20445 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20447 /* This is actually the number of fp registers that hold parameters;
20448 and thus the maximum value is 13. */
20449 /* Set parameters on stack bit if parameters are not in their original
20450 registers, regardless of whether they are on the stack? Xlc
20451 seems to set the bit when not optimizing. */
20452 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20454 if (! optional_tbtab)
20457 /* Optional fields follow. Some are variable length. */
20459 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20460 11 double float. */
20461 /* There is an entry for each parameter in a register, in the order that
20462 they occur in the parameter list. Any intervening arguments on the
20463 stack are ignored. If the list overflows a long (max possible length
20464 34 bits) then completely leave off all elements that don't fit. */
20465 /* Only emit this long if there was at least one parameter. */
20466 if (fixed_parms || float_parms)
20467 fprintf (file, "\t.long %d\n", parm_info);
20469 /* Offset from start of code to tb table. */
20470 fputs ("\t.long ", file);
20471 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20473 RS6000_OUTPUT_BASENAME (file, fname);
20475 assemble_name (file, fname);
20477 rs6000_output_function_entry (file, fname);
20480 /* Interrupt handler mask. */
20481 /* Omit this long, since we never set the interrupt handler bit
20484 /* Number of CTL (controlled storage) anchors. */
20485 /* Omit this long, since the has_ctl bit is never set above. */
20487 /* Displacement into stack of each CTL anchor. */
20488 /* Omit this list of longs, because there are no CTL anchors. */
20490 /* Length of function name. */
20493 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20495 /* Function name. */
20496 assemble_string (fname, strlen (fname));
20498 /* Register for alloca automatic storage; this is always reg 31.
20499 Only emit this if the alloca bit was set above. */
20500 if (frame_pointer_needed)
20501 fputs ("\t.byte 31\n", file);
20503 fputs ("\t.align 2\n", file);
20507 /* A C compound statement that outputs the assembler code for a thunk
20508 function, used to implement C++ virtual function calls with
20509 multiple inheritance. The thunk acts as a wrapper around a virtual
20510 function, adjusting the implicit object parameter before handing
20511 control off to the real function.
20513 First, emit code to add the integer DELTA to the location that
20514 contains the incoming first argument. Assume that this argument
20515 contains a pointer, and is the one used to pass the `this' pointer
20516 in C++. This is the incoming argument *before* the function
20517 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20518 values of all other incoming arguments.
20520 After the addition, emit code to jump to FUNCTION, which is a
20521 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20522 not touch the return address. Hence returning from FUNCTION will
20523 return to whoever called the current `thunk'.
20525 The effect must be as if FUNCTION had been called directly with the
20526 adjusted first argument. This macro is responsible for emitting
20527 all of the code for a thunk function; output_function_prologue()
20528 and output_function_epilogue() are not invoked.
20530 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20531 been extracted from it.) It might possibly be useful on some
20532 targets, but probably not.
20534 If you do not define this macro, the target-independent code in the
20535 C++ frontend will generate a less efficient heavyweight thunk that
20536 calls FUNCTION instead of jumping to it. The generic approach does
20537 not support varargs. */
20540 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20541 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20544 rtx this_rtx, insn, funexp;
20546 reload_completed = 1;
20547 epilogue_completed = 1;
20549 /* Mark the end of the (empty) prologue. */
20550 emit_note (NOTE_INSN_PROLOGUE_END);
20552 /* Find the "this" pointer. If the function returns a structure,
20553 the structure return pointer is in r3. */
20554 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20555 this_rtx = gen_rtx_REG (Pmode, 4);
20557 this_rtx = gen_rtx_REG (Pmode, 3);
20559 /* Apply the constant offset, if required. */
20561 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20563 /* Apply the offset from the vtable, if required. */
20566 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20567 rtx tmp = gen_rtx_REG (Pmode, 12);
20569 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20570 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20572 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20573 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20577 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20579 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20581 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20584 /* Generate a tail call to the target function. */
20585 if (!TREE_USED (function))
20587 assemble_external (function);
20588 TREE_USED (function) = 1;
20590 funexp = XEXP (DECL_RTL (function), 0);
20591 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20594 if (MACHOPIC_INDIRECT)
20595 funexp = machopic_indirect_call_target (funexp);
20598 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20599 generate sibcall RTL explicitly. */
20600 insn = emit_call_insn (
20601 gen_rtx_PARALLEL (VOIDmode,
20603 gen_rtx_CALL (VOIDmode,
20604 funexp, const0_rtx),
20605 gen_rtx_USE (VOIDmode, const0_rtx),
20606 gen_rtx_USE (VOIDmode,
20607 gen_rtx_REG (SImode,
20609 gen_rtx_RETURN (VOIDmode))));
20610 SIBLING_CALL_P (insn) = 1;
20613 /* Run just enough of rest_of_compilation to get the insns emitted.
20614 There's not really enough bulk here to make other passes such as
20615 instruction scheduling worth while. Note that use_thunk calls
20616 assemble_start_function and assemble_end_function. */
20617 insn = get_insns ();
20618 insn_locators_alloc ();
20619 shorten_branches (insn);
20620 final_start_function (insn, file, 1);
20621 final (insn, file, 1);
20622 final_end_function ();
20624 reload_completed = 0;
20625 epilogue_completed = 0;
20628 /* A quick summary of the various types of 'constant-pool tables'
20631 Target Flags Name One table per
20632 AIX (none) AIX TOC object file
20633 AIX -mfull-toc AIX TOC object file
20634 AIX -mminimal-toc AIX minimal TOC translation unit
20635 SVR4/EABI (none) SVR4 SDATA object file
20636 SVR4/EABI -fpic SVR4 pic object file
20637 SVR4/EABI -fPIC SVR4 PIC translation unit
20638 SVR4/EABI -mrelocatable EABI TOC function
20639 SVR4/EABI -maix AIX TOC object file
20640 SVR4/EABI -maix -mminimal-toc
20641 AIX minimal TOC translation unit
20643 Name Reg. Set by entries contains:
20644 made by addrs? fp? sum?
20646 AIX TOC 2 crt0 as Y option option
20647 AIX minimal TOC 30 prolog gcc Y Y option
20648 SVR4 SDATA 13 crt0 gcc N Y N
20649 SVR4 pic 30 prolog ld Y not yet N
20650 SVR4 PIC 30 prolog gcc Y option option
20651 EABI TOC 30 prolog gcc Y option option
20655 /* Hash functions for the hash table. */
20658 rs6000_hash_constant (rtx k)
20660 enum rtx_code code = GET_CODE (k);
20661 enum machine_mode mode = GET_MODE (k);
20662 unsigned result = (code << 3) ^ mode;
20663 const char *format;
20666 format = GET_RTX_FORMAT (code);
20667 flen = strlen (format);
20673 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20676 if (mode != VOIDmode)
20677 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20689 for (; fidx < flen; fidx++)
20690 switch (format[fidx])
20695 const char *str = XSTR (k, fidx);
20696 len = strlen (str);
20697 result = result * 613 + len;
20698 for (i = 0; i < len; i++)
20699 result = result * 613 + (unsigned) str[i];
20704 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20708 result = result * 613 + (unsigned) XINT (k, fidx);
20711 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20712 result = result * 613 + (unsigned) XWINT (k, fidx);
20716 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20717 result = result * 613 + (unsigned) (XWINT (k, fidx)
20724 gcc_unreachable ();
20731 toc_hash_function (const void *hash_entry)
20733 const struct toc_hash_struct *thc =
20734 (const struct toc_hash_struct *) hash_entry;
20735 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20738 /* Compare H1 and H2 for equivalence. */
20741 toc_hash_eq (const void *h1, const void *h2)
20743 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20744 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20746 if (((const struct toc_hash_struct *) h1)->key_mode
20747 != ((const struct toc_hash_struct *) h2)->key_mode)
20750 return rtx_equal_p (r1, r2);
20753 /* These are the names given by the C++ front-end to vtables, and
20754 vtable-like objects. Ideally, this logic should not be here;
20755 instead, there should be some programmatic way of inquiring as
20756 to whether or not an object is a vtable. */
20758 #define VTABLE_NAME_P(NAME) \
20759 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20760 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20761 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20762 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20763 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20765 #ifdef NO_DOLLAR_IN_LABEL
20766 /* Return a GGC-allocated character string translating dollar signs in
20767 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20770 rs6000_xcoff_strip_dollar (const char *name)
20775 p = strchr (name, '$');
20777 if (p == 0 || p == name)
20780 len = strlen (name);
20781 strip = (char *) alloca (len + 1);
20782 strcpy (strip, name);
20783 p = strchr (strip, '$');
20787 p = strchr (p + 1, '$');
20790 return ggc_alloc_string (strip, len);
20795 rs6000_output_symbol_ref (FILE *file, rtx x)
20797 /* Currently C++ toc references to vtables can be emitted before it
20798 is decided whether the vtable is public or private. If this is
20799 the case, then the linker will eventually complain that there is
20800 a reference to an unknown section. Thus, for vtables only,
20801 we emit the TOC reference to reference the symbol and not the
20803 const char *name = XSTR (x, 0);
20805 if (VTABLE_NAME_P (name))
20807 RS6000_OUTPUT_BASENAME (file, name);
20810 assemble_name (file, name);
20813 /* Output a TOC entry. We derive the entry name from what is being
20817 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20820 const char *name = buf;
20822 HOST_WIDE_INT offset = 0;
20824 gcc_assert (!TARGET_NO_TOC);
20826 /* When the linker won't eliminate them, don't output duplicate
20827 TOC entries (this happens on AIX if there is any kind of TOC,
20828 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20830 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20832 struct toc_hash_struct *h;
20835 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20836 time because GGC is not initialized at that point. */
20837 if (toc_hash_table == NULL)
20838 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20839 toc_hash_eq, NULL);
20841 h = GGC_NEW (struct toc_hash_struct);
20843 h->key_mode = mode;
20844 h->labelno = labelno;
20846 found = htab_find_slot (toc_hash_table, h, INSERT);
20847 if (*found == NULL)
20849 else /* This is indeed a duplicate.
20850 Set this label equal to that label. */
20852 fputs ("\t.set ", file);
20853 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20854 fprintf (file, "%d,", labelno);
20855 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20856 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20862 /* If we're going to put a double constant in the TOC, make sure it's
20863 aligned properly when strict alignment is on. */
20864 if (GET_CODE (x) == CONST_DOUBLE
20865 && STRICT_ALIGNMENT
20866 && GET_MODE_BITSIZE (mode) >= 64
20867 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20868 ASM_OUTPUT_ALIGN (file, 3);
20871 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20873 /* Handle FP constants specially. Note that if we have a minimal
20874 TOC, things we put here aren't actually in the TOC, so we can allow
20876 if (GET_CODE (x) == CONST_DOUBLE &&
20877 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20879 REAL_VALUE_TYPE rv;
20882 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20883 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20884 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20886 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20890 if (TARGET_MINIMAL_TOC)
20891 fputs (DOUBLE_INT_ASM_OP, file);
20893 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20894 k[0] & 0xffffffff, k[1] & 0xffffffff,
20895 k[2] & 0xffffffff, k[3] & 0xffffffff);
20896 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20897 k[0] & 0xffffffff, k[1] & 0xffffffff,
20898 k[2] & 0xffffffff, k[3] & 0xffffffff);
20903 if (TARGET_MINIMAL_TOC)
20904 fputs ("\t.long ", file);
20906 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20907 k[0] & 0xffffffff, k[1] & 0xffffffff,
20908 k[2] & 0xffffffff, k[3] & 0xffffffff);
20909 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20910 k[0] & 0xffffffff, k[1] & 0xffffffff,
20911 k[2] & 0xffffffff, k[3] & 0xffffffff);
20915 else if (GET_CODE (x) == CONST_DOUBLE &&
20916 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20918 REAL_VALUE_TYPE rv;
20921 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20923 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20924 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20926 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20930 if (TARGET_MINIMAL_TOC)
20931 fputs (DOUBLE_INT_ASM_OP, file);
20933 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20934 k[0] & 0xffffffff, k[1] & 0xffffffff);
20935 fprintf (file, "0x%lx%08lx\n",
20936 k[0] & 0xffffffff, k[1] & 0xffffffff);
20941 if (TARGET_MINIMAL_TOC)
20942 fputs ("\t.long ", file);
20944 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20945 k[0] & 0xffffffff, k[1] & 0xffffffff);
20946 fprintf (file, "0x%lx,0x%lx\n",
20947 k[0] & 0xffffffff, k[1] & 0xffffffff);
20951 else if (GET_CODE (x) == CONST_DOUBLE &&
20952 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20954 REAL_VALUE_TYPE rv;
20957 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20958 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20959 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20961 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20965 if (TARGET_MINIMAL_TOC)
20966 fputs (DOUBLE_INT_ASM_OP, file);
20968 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20969 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20974 if (TARGET_MINIMAL_TOC)
20975 fputs ("\t.long ", file);
20977 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20978 fprintf (file, "0x%lx\n", l & 0xffffffff);
20982 else if (GET_MODE (x) == VOIDmode
20983 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20985 unsigned HOST_WIDE_INT low;
20986 HOST_WIDE_INT high;
20988 if (GET_CODE (x) == CONST_DOUBLE)
20990 low = CONST_DOUBLE_LOW (x);
20991 high = CONST_DOUBLE_HIGH (x);
20994 #if HOST_BITS_PER_WIDE_INT == 32
20997 high = (low & 0x80000000) ? ~0 : 0;
21001 low = INTVAL (x) & 0xffffffff;
21002 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21006 /* TOC entries are always Pmode-sized, but since this
21007 is a bigendian machine then if we're putting smaller
21008 integer constants in the TOC we have to pad them.
21009 (This is still a win over putting the constants in
21010 a separate constant pool, because then we'd have
21011 to have both a TOC entry _and_ the actual constant.)
21013 For a 32-bit target, CONST_INT values are loaded and shifted
21014 entirely within `low' and can be stored in one TOC entry. */
21016 /* It would be easy to make this work, but it doesn't now. */
21017 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21019 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21021 #if HOST_BITS_PER_WIDE_INT == 32
21022 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21023 POINTER_SIZE, &low, &high, 0);
21026 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21027 high = (HOST_WIDE_INT) low >> 32;
21034 if (TARGET_MINIMAL_TOC)
21035 fputs (DOUBLE_INT_ASM_OP, file);
21037 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21038 (long) high & 0xffffffff, (long) low & 0xffffffff);
21039 fprintf (file, "0x%lx%08lx\n",
21040 (long) high & 0xffffffff, (long) low & 0xffffffff);
21045 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21047 if (TARGET_MINIMAL_TOC)
21048 fputs ("\t.long ", file);
21050 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21051 (long) high & 0xffffffff, (long) low & 0xffffffff);
21052 fprintf (file, "0x%lx,0x%lx\n",
21053 (long) high & 0xffffffff, (long) low & 0xffffffff);
21057 if (TARGET_MINIMAL_TOC)
21058 fputs ("\t.long ", file);
21060 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21061 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21067 if (GET_CODE (x) == CONST)
21069 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21070 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21072 base = XEXP (XEXP (x, 0), 0);
21073 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21076 switch (GET_CODE (base))
21079 name = XSTR (base, 0);
21083 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21084 CODE_LABEL_NUMBER (XEXP (base, 0)));
21088 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21092 gcc_unreachable ();
21095 if (TARGET_MINIMAL_TOC)
21096 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21099 fputs ("\t.tc ", file);
21100 RS6000_OUTPUT_BASENAME (file, name);
21103 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21105 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21107 fputs ("[TC],", file);
21110 /* Currently C++ toc references to vtables can be emitted before it
21111 is decided whether the vtable is public or private. If this is
21112 the case, then the linker will eventually complain that there is
21113 a TOC reference to an unknown section. Thus, for vtables only,
21114 we emit the TOC reference to reference the symbol and not the
21116 if (VTABLE_NAME_P (name))
21118 RS6000_OUTPUT_BASENAME (file, name);
21120 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21121 else if (offset > 0)
21122 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21125 output_addr_const (file, x);
21129 /* Output an assembler pseudo-op to write an ASCII string of N characters
21130 starting at P to FILE.
21132 On the RS/6000, we have to do this using the .byte operation and
21133 write out special characters outside the quoted string.
21134 Also, the assembler is broken; very long strings are truncated,
21135 so we must artificially break them up early. */
21138 output_ascii (FILE *file, const char *p, int n)
21141 int i, count_string;
21142 const char *for_string = "\t.byte \"";
21143 const char *for_decimal = "\t.byte ";
21144 const char *to_close = NULL;
21147 for (i = 0; i < n; i++)
21150 if (c >= ' ' && c < 0177)
21153 fputs (for_string, file);
21156 /* Write two quotes to get one. */
21164 for_decimal = "\"\n\t.byte ";
21168 if (count_string >= 512)
21170 fputs (to_close, file);
21172 for_string = "\t.byte \"";
21173 for_decimal = "\t.byte ";
21181 fputs (for_decimal, file);
21182 fprintf (file, "%d", c);
21184 for_string = "\n\t.byte \"";
21185 for_decimal = ", ";
21191 /* Now close the string if we have written one. Then end the line. */
21193 fputs (to_close, file);
21196 /* Generate a unique section name for FILENAME for a section type
21197 represented by SECTION_DESC. Output goes into BUF.
21199 SECTION_DESC can be any string, as long as it is different for each
21200 possible section type.
21202 We name the section in the same manner as xlc. The name begins with an
21203 underscore followed by the filename (after stripping any leading directory
21204 names) with the last period replaced by the string SECTION_DESC. If
21205 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21209 rs6000_gen_section_name (char **buf, const char *filename,
21210 const char *section_desc)
21212 const char *q, *after_last_slash, *last_period = 0;
21216 after_last_slash = filename;
21217 for (q = filename; *q; q++)
21220 after_last_slash = q + 1;
21221 else if (*q == '.')
21225 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21226 *buf = (char *) xmalloc (len);
21231 for (q = after_last_slash; *q; q++)
21233 if (q == last_period)
21235 strcpy (p, section_desc);
21236 p += strlen (section_desc);
21240 else if (ISALNUM (*q))
21244 if (last_period == 0)
21245 strcpy (p, section_desc);
21250 /* Emit profile function. */
21253 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21255 /* Non-standard profiling for kernels, which just saves LR then calls
21256 _mcount without worrying about arg saves. The idea is to change
21257 the function prologue as little as possible as it isn't easy to
21258 account for arg save/restore code added just for _mcount. */
21259 if (TARGET_PROFILE_KERNEL)
21262 if (DEFAULT_ABI == ABI_AIX)
21264 #ifndef NO_PROFILE_COUNTERS
21265 # define NO_PROFILE_COUNTERS 0
21267 if (NO_PROFILE_COUNTERS)
21268 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21269 LCT_NORMAL, VOIDmode, 0);
21273 const char *label_name;
21276 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21277 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21278 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21280 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21281 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21284 else if (DEFAULT_ABI == ABI_DARWIN)
21286 const char *mcount_name = RS6000_MCOUNT;
21287 int caller_addr_regno = LR_REGNO;
21289 /* Be conservative and always set this, at least for now. */
21290 crtl->uses_pic_offset_table = 1;
21293 /* For PIC code, set up a stub and collect the caller's address
21294 from r0, which is where the prologue puts it. */
21295 if (MACHOPIC_INDIRECT
21296 && crtl->uses_pic_offset_table)
21297 caller_addr_regno = 0;
21299 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21300 LCT_NORMAL, VOIDmode, 1,
21301 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21305 /* Write function profiler code. */
21308 output_function_profiler (FILE *file, int labelno)
21312 switch (DEFAULT_ABI)
21315 gcc_unreachable ();
21320 warning (0, "no profiling of 64-bit code for this ABI");
21323 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21324 fprintf (file, "\tmflr %s\n", reg_names[0]);
21325 if (NO_PROFILE_COUNTERS)
21327 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21328 reg_names[0], reg_names[1]);
21330 else if (TARGET_SECURE_PLT && flag_pic)
21332 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21333 reg_names[0], reg_names[1]);
21334 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21335 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21336 reg_names[12], reg_names[12]);
21337 assemble_name (file, buf);
21338 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21339 assemble_name (file, buf);
21340 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21342 else if (flag_pic == 1)
21344 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21345 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21346 reg_names[0], reg_names[1]);
21347 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21348 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21349 assemble_name (file, buf);
21350 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21352 else if (flag_pic > 1)
21354 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21355 reg_names[0], reg_names[1]);
21356 /* Now, we need to get the address of the label. */
21357 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21358 assemble_name (file, buf);
21359 fputs ("-.\n1:", file);
21360 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21361 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21362 reg_names[0], reg_names[11]);
21363 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21364 reg_names[0], reg_names[0], reg_names[11]);
21368 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21369 assemble_name (file, buf);
21370 fputs ("@ha\n", file);
21371 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21372 reg_names[0], reg_names[1]);
21373 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21374 assemble_name (file, buf);
21375 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21378 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21379 fprintf (file, "\tbl %s%s\n",
21380 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21385 if (!TARGET_PROFILE_KERNEL)
21387 /* Don't do anything, done in output_profile_hook (). */
21391 gcc_assert (!TARGET_32BIT);
21393 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21394 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21396 if (cfun->static_chain_decl != NULL)
21398 asm_fprintf (file, "\tstd %s,24(%s)\n",
21399 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21400 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21401 asm_fprintf (file, "\tld %s,24(%s)\n",
21402 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21405 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21413 /* The following variable value is the last issued insn. */
21415 static rtx last_scheduled_insn;
21417 /* The following variable helps to balance issuing of load and
21418 store instructions */
21420 static int load_store_pendulum;
21422 /* Power4 load update and store update instructions are cracked into a
21423 load or store and an integer insn which are executed in the same cycle.
21424 Branches have their own dispatch slot which does not count against the
21425 GCC issue rate, but it changes the program flow so there are no other
21426 instructions to issue in this cycle. */
21429 rs6000_variable_issue_1 (rtx insn, int more)
21431 last_scheduled_insn = insn;
21432 if (GET_CODE (PATTERN (insn)) == USE
21433 || GET_CODE (PATTERN (insn)) == CLOBBER)
21435 cached_can_issue_more = more;
21436 return cached_can_issue_more;
21439 if (insn_terminates_group_p (insn, current_group))
21441 cached_can_issue_more = 0;
21442 return cached_can_issue_more;
21445 /* If no reservation, but reach here */
21446 if (recog_memoized (insn) < 0)
21449 if (rs6000_sched_groups)
21451 if (is_microcoded_insn (insn))
21452 cached_can_issue_more = 0;
21453 else if (is_cracked_insn (insn))
21454 cached_can_issue_more = more > 2 ? more - 2 : 0;
21456 cached_can_issue_more = more - 1;
21458 return cached_can_issue_more;
21461 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21464 cached_can_issue_more = more - 1;
21465 return cached_can_issue_more;
21469 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21471 int r = rs6000_variable_issue_1 (insn, more);
21473 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21477 /* Adjust the cost of a scheduling dependency. Return the new cost of
21478 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21481 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21483 enum attr_type attr_type;
21485 if (! recog_memoized (insn))
21488 switch (REG_NOTE_KIND (link))
21492 /* Data dependency; DEP_INSN writes a register that INSN reads
21493 some cycles later. */
21495 /* Separate a load from a narrower, dependent store. */
21496 if (rs6000_sched_groups
21497 && GET_CODE (PATTERN (insn)) == SET
21498 && GET_CODE (PATTERN (dep_insn)) == SET
21499 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21500 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21501 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21502 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21505 attr_type = get_attr_type (insn);
21510 /* Tell the first scheduling pass about the latency between
21511 a mtctr and bctr (and mtlr and br/blr). The first
21512 scheduling pass will not know about this latency since
21513 the mtctr instruction, which has the latency associated
21514 to it, will be generated by reload. */
21515 return TARGET_POWER ? 5 : 4;
21517 /* Leave some extra cycles between a compare and its
21518 dependent branch, to inhibit expensive mispredicts. */
21519 if ((rs6000_cpu_attr == CPU_PPC603
21520 || rs6000_cpu_attr == CPU_PPC604
21521 || rs6000_cpu_attr == CPU_PPC604E
21522 || rs6000_cpu_attr == CPU_PPC620
21523 || rs6000_cpu_attr == CPU_PPC630
21524 || rs6000_cpu_attr == CPU_PPC750
21525 || rs6000_cpu_attr == CPU_PPC7400
21526 || rs6000_cpu_attr == CPU_PPC7450
21527 || rs6000_cpu_attr == CPU_POWER4
21528 || rs6000_cpu_attr == CPU_POWER5
21529 || rs6000_cpu_attr == CPU_POWER7
21530 || rs6000_cpu_attr == CPU_CELL)
21531 && recog_memoized (dep_insn)
21532 && (INSN_CODE (dep_insn) >= 0))
21534 switch (get_attr_type (dep_insn))
21538 case TYPE_DELAYED_COMPARE:
21539 case TYPE_IMUL_COMPARE:
21540 case TYPE_LMUL_COMPARE:
21541 case TYPE_FPCOMPARE:
21542 case TYPE_CR_LOGICAL:
21543 case TYPE_DELAYED_CR:
21552 case TYPE_STORE_UX:
21554 case TYPE_FPSTORE_U:
21555 case TYPE_FPSTORE_UX:
21556 if ((rs6000_cpu == PROCESSOR_POWER6)
21557 && recog_memoized (dep_insn)
21558 && (INSN_CODE (dep_insn) >= 0))
21561 if (GET_CODE (PATTERN (insn)) != SET)
21562 /* If this happens, we have to extend this to schedule
21563 optimally. Return default for now. */
21566 /* Adjust the cost for the case where the value written
21567 by a fixed point operation is used as the address
21568 gen value on a store. */
21569 switch (get_attr_type (dep_insn))
21576 if (! store_data_bypass_p (dep_insn, insn))
21580 case TYPE_LOAD_EXT:
21581 case TYPE_LOAD_EXT_U:
21582 case TYPE_LOAD_EXT_UX:
21583 case TYPE_VAR_SHIFT_ROTATE:
21584 case TYPE_VAR_DELAYED_COMPARE:
21586 if (! store_data_bypass_p (dep_insn, insn))
21592 case TYPE_FAST_COMPARE:
21595 case TYPE_INSERT_WORD:
21596 case TYPE_INSERT_DWORD:
21597 case TYPE_FPLOAD_U:
21598 case TYPE_FPLOAD_UX:
21600 case TYPE_STORE_UX:
21601 case TYPE_FPSTORE_U:
21602 case TYPE_FPSTORE_UX:
21604 if (! store_data_bypass_p (dep_insn, insn))
21612 case TYPE_IMUL_COMPARE:
21613 case TYPE_LMUL_COMPARE:
21615 if (! store_data_bypass_p (dep_insn, insn))
21621 if (! store_data_bypass_p (dep_insn, insn))
21627 if (! store_data_bypass_p (dep_insn, insn))
21640 case TYPE_LOAD_EXT:
21641 case TYPE_LOAD_EXT_U:
21642 case TYPE_LOAD_EXT_UX:
21643 if ((rs6000_cpu == PROCESSOR_POWER6)
21644 && recog_memoized (dep_insn)
21645 && (INSN_CODE (dep_insn) >= 0))
21648 /* Adjust the cost for the case where the value written
21649 by a fixed point instruction is used within the address
21650 gen portion of a subsequent load(u)(x) */
21651 switch (get_attr_type (dep_insn))
21658 if (set_to_load_agen (dep_insn, insn))
21662 case TYPE_LOAD_EXT:
21663 case TYPE_LOAD_EXT_U:
21664 case TYPE_LOAD_EXT_UX:
21665 case TYPE_VAR_SHIFT_ROTATE:
21666 case TYPE_VAR_DELAYED_COMPARE:
21668 if (set_to_load_agen (dep_insn, insn))
21674 case TYPE_FAST_COMPARE:
21677 case TYPE_INSERT_WORD:
21678 case TYPE_INSERT_DWORD:
21679 case TYPE_FPLOAD_U:
21680 case TYPE_FPLOAD_UX:
21682 case TYPE_STORE_UX:
21683 case TYPE_FPSTORE_U:
21684 case TYPE_FPSTORE_UX:
21686 if (set_to_load_agen (dep_insn, insn))
21694 case TYPE_IMUL_COMPARE:
21695 case TYPE_LMUL_COMPARE:
21697 if (set_to_load_agen (dep_insn, insn))
21703 if (set_to_load_agen (dep_insn, insn))
21709 if (set_to_load_agen (dep_insn, insn))
21720 if ((rs6000_cpu == PROCESSOR_POWER6)
21721 && recog_memoized (dep_insn)
21722 && (INSN_CODE (dep_insn) >= 0)
21723 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21730 /* Fall out to return default cost. */
21734 case REG_DEP_OUTPUT:
21735 /* Output dependency; DEP_INSN writes a register that INSN writes some
21737 if ((rs6000_cpu == PROCESSOR_POWER6)
21738 && recog_memoized (dep_insn)
21739 && (INSN_CODE (dep_insn) >= 0))
21741 attr_type = get_attr_type (insn);
21746 if (get_attr_type (dep_insn) == TYPE_FP)
21750 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21758 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21763 gcc_unreachable ();
21769 /* Debug version of rs6000_adjust_cost. */
21772 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21774 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21780 switch (REG_NOTE_KIND (link))
21782 default: dep = "unknown depencency"; break;
21783 case REG_DEP_TRUE: dep = "data dependency"; break;
21784 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21785 case REG_DEP_ANTI: dep = "anti depencency"; break;
21789 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21790 "%s, insn:\n", ret, cost, dep);
21798 /* The function returns a true if INSN is microcoded.
21799 Return false otherwise. */
21802 is_microcoded_insn (rtx insn)
21804 if (!insn || !NONDEBUG_INSN_P (insn)
21805 || GET_CODE (PATTERN (insn)) == USE
21806 || GET_CODE (PATTERN (insn)) == CLOBBER)
21809 if (rs6000_cpu_attr == CPU_CELL)
21810 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21812 if (rs6000_sched_groups)
21814 enum attr_type type = get_attr_type (insn);
21815 if (type == TYPE_LOAD_EXT_U
21816 || type == TYPE_LOAD_EXT_UX
21817 || type == TYPE_LOAD_UX
21818 || type == TYPE_STORE_UX
21819 || type == TYPE_MFCR)
21826 /* The function returns true if INSN is cracked into 2 instructions
21827 by the processor (and therefore occupies 2 issue slots). */
21830 is_cracked_insn (rtx insn)
21832 if (!insn || !NONDEBUG_INSN_P (insn)
21833 || GET_CODE (PATTERN (insn)) == USE
21834 || GET_CODE (PATTERN (insn)) == CLOBBER)
21837 if (rs6000_sched_groups)
21839 enum attr_type type = get_attr_type (insn);
21840 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21841 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21842 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21843 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21844 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21845 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21846 || type == TYPE_IDIV || type == TYPE_LDIV
21847 || type == TYPE_INSERT_WORD)
21854 /* The function returns true if INSN can be issued only from
21855 the branch slot. */
21858 is_branch_slot_insn (rtx insn)
21860 if (!insn || !NONDEBUG_INSN_P (insn)
21861 || GET_CODE (PATTERN (insn)) == USE
21862 || GET_CODE (PATTERN (insn)) == CLOBBER)
21865 if (rs6000_sched_groups)
21867 enum attr_type type = get_attr_type (insn);
21868 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21876 /* The function returns true if out_inst sets a value that is
21877 used in the address generation computation of in_insn */
21879 set_to_load_agen (rtx out_insn, rtx in_insn)
21881 rtx out_set, in_set;
21883 /* For performance reasons, only handle the simple case where
21884 both loads are a single_set. */
21885 out_set = single_set (out_insn);
21888 in_set = single_set (in_insn);
21890 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21896 /* The function returns true if the target storage location of
21897 out_insn is adjacent to the target storage location of in_insn */
21898 /* Return 1 if memory locations are adjacent. */
21901 adjacent_mem_locations (rtx insn1, rtx insn2)
21904 rtx a = get_store_dest (PATTERN (insn1));
21905 rtx b = get_store_dest (PATTERN (insn2));
21907 if ((GET_CODE (XEXP (a, 0)) == REG
21908 || (GET_CODE (XEXP (a, 0)) == PLUS
21909 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21910 && (GET_CODE (XEXP (b, 0)) == REG
21911 || (GET_CODE (XEXP (b, 0)) == PLUS
21912 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21914 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21917 if (GET_CODE (XEXP (a, 0)) == PLUS)
21919 reg0 = XEXP (XEXP (a, 0), 0);
21920 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21923 reg0 = XEXP (a, 0);
21925 if (GET_CODE (XEXP (b, 0)) == PLUS)
21927 reg1 = XEXP (XEXP (b, 0), 0);
21928 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21931 reg1 = XEXP (b, 0);
21933 val_diff = val1 - val0;
21935 return ((REGNO (reg0) == REGNO (reg1))
21936 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21937 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21943 /* A C statement (sans semicolon) to update the integer scheduling
21944 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21945 INSN earlier, reduce the priority to execute INSN later. Do not
21946 define this macro if you do not need to adjust the scheduling
21947 priorities of insns. */
21950 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21952 /* On machines (like the 750) which have asymmetric integer units,
21953 where one integer unit can do multiply and divides and the other
21954 can't, reduce the priority of multiply/divide so it is scheduled
21955 before other integer operations. */
21958 if (! INSN_P (insn))
21961 if (GET_CODE (PATTERN (insn)) == USE)
21964 switch (rs6000_cpu_attr) {
21966 switch (get_attr_type (insn))
21973 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21974 priority, priority);
21975 if (priority >= 0 && priority < 0x01000000)
21982 if (insn_must_be_first_in_group (insn)
21983 && reload_completed
21984 && current_sched_info->sched_max_insns_priority
21985 && rs6000_sched_restricted_insns_priority)
21988 /* Prioritize insns that can be dispatched only in the first
21990 if (rs6000_sched_restricted_insns_priority == 1)
21991 /* Attach highest priority to insn. This means that in
21992 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21993 precede 'priority' (critical path) considerations. */
21994 return current_sched_info->sched_max_insns_priority;
21995 else if (rs6000_sched_restricted_insns_priority == 2)
21996 /* Increase priority of insn by a minimal amount. This means that in
21997 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21998 considerations precede dispatch-slot restriction considerations. */
21999 return (priority + 1);
22002 if (rs6000_cpu == PROCESSOR_POWER6
22003 && ((load_store_pendulum == -2 && is_load_insn (insn))
22004 || (load_store_pendulum == 2 && is_store_insn (insn))))
22005 /* Attach highest priority to insn if the scheduler has just issued two
22006 stores and this instruction is a load, or two loads and this instruction
22007 is a store. Power6 wants loads and stores scheduled alternately
22009 return current_sched_info->sched_max_insns_priority;
22014 /* Return true if the instruction is nonpipelined on the Cell. */
22016 is_nonpipeline_insn (rtx insn)
22018 enum attr_type type;
22019 if (!insn || !NONDEBUG_INSN_P (insn)
22020 || GET_CODE (PATTERN (insn)) == USE
22021 || GET_CODE (PATTERN (insn)) == CLOBBER)
22024 type = get_attr_type (insn);
22025 if (type == TYPE_IMUL
22026 || type == TYPE_IMUL2
22027 || type == TYPE_IMUL3
22028 || type == TYPE_LMUL
22029 || type == TYPE_IDIV
22030 || type == TYPE_LDIV
22031 || type == TYPE_SDIV
22032 || type == TYPE_DDIV
22033 || type == TYPE_SSQRT
22034 || type == TYPE_DSQRT
22035 || type == TYPE_MFCR
22036 || type == TYPE_MFCRF
22037 || type == TYPE_MFJMPR)
22045 /* Return how many instructions the machine can issue per cycle. */
22048 rs6000_issue_rate (void)
22050 /* Unless scheduling for register pressure, use issue rate of 1 for
22051 first scheduling pass to decrease degradation. */
22052 if (!reload_completed && !flag_sched_pressure)
22055 switch (rs6000_cpu_attr) {
22056 case CPU_RIOS1: /* ? */
22058 case CPU_PPC601: /* ? */
22067 case CPU_PPCE300C2:
22068 case CPU_PPCE300C3:
22069 case CPU_PPCE500MC:
22070 case CPU_PPCE500MC64:
22089 /* Return how many instructions to look ahead for better insn
22093 rs6000_use_sched_lookahead (void)
22095 if (rs6000_cpu_attr == CPU_PPC8540)
22097 if (rs6000_cpu_attr == CPU_CELL)
22098 return (reload_completed ? 8 : 0);
22102 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22104 rs6000_use_sched_lookahead_guard (rtx insn)
22106 if (rs6000_cpu_attr != CPU_CELL)
22109 if (insn == NULL_RTX || !INSN_P (insn))
22112 if (!reload_completed
22113 || is_nonpipeline_insn (insn)
22114 || is_microcoded_insn (insn))
22120 /* Determine is PAT refers to memory. */
22123 is_mem_ref (rtx pat)
22129 /* stack_tie does not produce any real memory traffic. */
22130 if (GET_CODE (pat) == UNSPEC
22131 && XINT (pat, 1) == UNSPEC_TIE)
22134 if (GET_CODE (pat) == MEM)
22137 /* Recursively process the pattern. */
22138 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22140 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22143 ret |= is_mem_ref (XEXP (pat, i));
22144 else if (fmt[i] == 'E')
22145 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22146 ret |= is_mem_ref (XVECEXP (pat, i, j));
22152 /* Determine if PAT is a PATTERN of a load insn. */
22155 is_load_insn1 (rtx pat)
22157 if (!pat || pat == NULL_RTX)
22160 if (GET_CODE (pat) == SET)
22161 return is_mem_ref (SET_SRC (pat));
22163 if (GET_CODE (pat) == PARALLEL)
22167 for (i = 0; i < XVECLEN (pat, 0); i++)
22168 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22175 /* Determine if INSN loads from memory. */
22178 is_load_insn (rtx insn)
22180 if (!insn || !INSN_P (insn))
22183 if (GET_CODE (insn) == CALL_INSN)
22186 return is_load_insn1 (PATTERN (insn));
22189 /* Determine if PAT is a PATTERN of a store insn. */
22192 is_store_insn1 (rtx pat)
22194 if (!pat || pat == NULL_RTX)
22197 if (GET_CODE (pat) == SET)
22198 return is_mem_ref (SET_DEST (pat));
22200 if (GET_CODE (pat) == PARALLEL)
22204 for (i = 0; i < XVECLEN (pat, 0); i++)
22205 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22212 /* Determine if INSN stores to memory. */
22215 is_store_insn (rtx insn)
22217 if (!insn || !INSN_P (insn))
22220 return is_store_insn1 (PATTERN (insn));
22223 /* Return the dest of a store insn. */
22226 get_store_dest (rtx pat)
22228 gcc_assert (is_store_insn1 (pat));
22230 if (GET_CODE (pat) == SET)
22231 return SET_DEST (pat);
22232 else if (GET_CODE (pat) == PARALLEL)
22236 for (i = 0; i < XVECLEN (pat, 0); i++)
22238 rtx inner_pat = XVECEXP (pat, 0, i);
22239 if (GET_CODE (inner_pat) == SET
22240 && is_mem_ref (SET_DEST (inner_pat)))
22244 /* We shouldn't get here, because we should have either a simple
22245 store insn or a store with update which are covered above. */
22249 /* Returns whether the dependence between INSN and NEXT is considered
22250 costly by the given target. */
22253 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22258 /* If the flag is not enabled - no dependence is considered costly;
22259 allow all dependent insns in the same group.
22260 This is the most aggressive option. */
22261 if (rs6000_sched_costly_dep == no_dep_costly)
22264 /* If the flag is set to 1 - a dependence is always considered costly;
22265 do not allow dependent instructions in the same group.
22266 This is the most conservative option. */
22267 if (rs6000_sched_costly_dep == all_deps_costly)
22270 insn = DEP_PRO (dep);
22271 next = DEP_CON (dep);
22273 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22274 && is_load_insn (next)
22275 && is_store_insn (insn))
22276 /* Prevent load after store in the same group. */
22279 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22280 && is_load_insn (next)
22281 && is_store_insn (insn)
22282 && DEP_TYPE (dep) == REG_DEP_TRUE)
22283 /* Prevent load after store in the same group if it is a true
22287 /* The flag is set to X; dependences with latency >= X are considered costly,
22288 and will not be scheduled in the same group. */
22289 if (rs6000_sched_costly_dep <= max_dep_latency
22290 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22296 /* Return the next insn after INSN that is found before TAIL is reached,
22297 skipping any "non-active" insns - insns that will not actually occupy
22298 an issue slot. Return NULL_RTX if such an insn is not found. */
22301 get_next_active_insn (rtx insn, rtx tail)
22303 if (insn == NULL_RTX || insn == tail)
22308 insn = NEXT_INSN (insn);
22309 if (insn == NULL_RTX || insn == tail)
22314 || (NONJUMP_INSN_P (insn)
22315 && GET_CODE (PATTERN (insn)) != USE
22316 && GET_CODE (PATTERN (insn)) != CLOBBER
22317 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22323 /* We are about to begin issuing insns for this clock cycle. */
22326 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22327 rtx *ready ATTRIBUTE_UNUSED,
22328 int *pn_ready ATTRIBUTE_UNUSED,
22329 int clock_var ATTRIBUTE_UNUSED)
22331 int n_ready = *pn_ready;
22334 fprintf (dump, "// rs6000_sched_reorder :\n");
22336 /* Reorder the ready list, if the second to last ready insn
22337 is a nonepipeline insn. */
22338 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22340 if (is_nonpipeline_insn (ready[n_ready - 1])
22341 && (recog_memoized (ready[n_ready - 2]) > 0))
22342 /* Simply swap first two insns. */
22344 rtx tmp = ready[n_ready - 1];
22345 ready[n_ready - 1] = ready[n_ready - 2];
22346 ready[n_ready - 2] = tmp;
22350 if (rs6000_cpu == PROCESSOR_POWER6)
22351 load_store_pendulum = 0;
22353 return rs6000_issue_rate ();
22356 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22359 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22360 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22363 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22365 /* For Power6, we need to handle some special cases to try and keep the
22366 store queue from overflowing and triggering expensive flushes.
22368 This code monitors how load and store instructions are being issued
22369 and skews the ready list one way or the other to increase the likelihood
22370 that a desired instruction is issued at the proper time.
22372 A couple of things are done. First, we maintain a "load_store_pendulum"
22373 to track the current state of load/store issue.
22375 - If the pendulum is at zero, then no loads or stores have been
22376 issued in the current cycle so we do nothing.
22378 - If the pendulum is 1, then a single load has been issued in this
22379 cycle and we attempt to locate another load in the ready list to
22382 - If the pendulum is -2, then two stores have already been
22383 issued in this cycle, so we increase the priority of the first load
22384 in the ready list to increase it's likelihood of being chosen first
22387 - If the pendulum is -1, then a single store has been issued in this
22388 cycle and we attempt to locate another store in the ready list to
22389 issue with it, preferring a store to an adjacent memory location to
22390 facilitate store pairing in the store queue.
22392 - If the pendulum is 2, then two loads have already been
22393 issued in this cycle, so we increase the priority of the first store
22394 in the ready list to increase it's likelihood of being chosen first
22397 - If the pendulum < -2 or > 2, then do nothing.
22399 Note: This code covers the most common scenarios. There exist non
22400 load/store instructions which make use of the LSU and which
22401 would need to be accounted for to strictly model the behavior
22402 of the machine. Those instructions are currently unaccounted
22403 for to help minimize compile time overhead of this code.
22405 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22411 if (is_store_insn (last_scheduled_insn))
22412 /* Issuing a store, swing the load_store_pendulum to the left */
22413 load_store_pendulum--;
22414 else if (is_load_insn (last_scheduled_insn))
22415 /* Issuing a load, swing the load_store_pendulum to the right */
22416 load_store_pendulum++;
22418 return cached_can_issue_more;
22420 /* If the pendulum is balanced, or there is only one instruction on
22421 the ready list, then all is well, so return. */
22422 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22423 return cached_can_issue_more;
22425 if (load_store_pendulum == 1)
22427 /* A load has been issued in this cycle. Scan the ready list
22428 for another load to issue with it */
22433 if (is_load_insn (ready[pos]))
22435 /* Found a load. Move it to the head of the ready list,
22436 and adjust it's priority so that it is more likely to
22439 for (i=pos; i<*pn_ready-1; i++)
22440 ready[i] = ready[i + 1];
22441 ready[*pn_ready-1] = tmp;
22443 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22444 INSN_PRIORITY (tmp)++;
22450 else if (load_store_pendulum == -2)
22452 /* Two stores have been issued in this cycle. Increase the
22453 priority of the first load in the ready list to favor it for
22454 issuing in the next cycle. */
22459 if (is_load_insn (ready[pos])
22461 && INSN_PRIORITY_KNOWN (ready[pos]))
22463 INSN_PRIORITY (ready[pos])++;
22465 /* Adjust the pendulum to account for the fact that a load
22466 was found and increased in priority. This is to prevent
22467 increasing the priority of multiple loads */
22468 load_store_pendulum--;
22475 else if (load_store_pendulum == -1)
22477 /* A store has been issued in this cycle. Scan the ready list for
22478 another store to issue with it, preferring a store to an adjacent
22480 int first_store_pos = -1;
22486 if (is_store_insn (ready[pos]))
22488 /* Maintain the index of the first store found on the
22490 if (first_store_pos == -1)
22491 first_store_pos = pos;
22493 if (is_store_insn (last_scheduled_insn)
22494 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22496 /* Found an adjacent store. Move it to the head of the
22497 ready list, and adjust it's priority so that it is
22498 more likely to stay there */
22500 for (i=pos; i<*pn_ready-1; i++)
22501 ready[i] = ready[i + 1];
22502 ready[*pn_ready-1] = tmp;
22504 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22505 INSN_PRIORITY (tmp)++;
22507 first_store_pos = -1;
22515 if (first_store_pos >= 0)
22517 /* An adjacent store wasn't found, but a non-adjacent store was,
22518 so move the non-adjacent store to the front of the ready
22519 list, and adjust its priority so that it is more likely to
22521 tmp = ready[first_store_pos];
22522 for (i=first_store_pos; i<*pn_ready-1; i++)
22523 ready[i] = ready[i + 1];
22524 ready[*pn_ready-1] = tmp;
22525 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22526 INSN_PRIORITY (tmp)++;
22529 else if (load_store_pendulum == 2)
22531 /* Two loads have been issued in this cycle. Increase the priority
22532 of the first store in the ready list to favor it for issuing in
22538 if (is_store_insn (ready[pos])
22540 && INSN_PRIORITY_KNOWN (ready[pos]))
22542 INSN_PRIORITY (ready[pos])++;
22544 /* Adjust the pendulum to account for the fact that a store
22545 was found and increased in priority. This is to prevent
22546 increasing the priority of multiple stores */
22547 load_store_pendulum++;
22556 return cached_can_issue_more;
22559 /* Return whether the presence of INSN causes a dispatch group termination
22560 of group WHICH_GROUP.
22562 If WHICH_GROUP == current_group, this function will return true if INSN
22563 causes the termination of the current group (i.e, the dispatch group to
22564 which INSN belongs). This means that INSN will be the last insn in the
22565 group it belongs to.
22567 If WHICH_GROUP == previous_group, this function will return true if INSN
22568 causes the termination of the previous group (i.e, the dispatch group that
22569 precedes the group to which INSN belongs). This means that INSN will be
22570 the first insn in the group it belongs to). */
22573 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22580 first = insn_must_be_first_in_group (insn);
22581 last = insn_must_be_last_in_group (insn);
22586 if (which_group == current_group)
22588 else if (which_group == previous_group)
22596 insn_must_be_first_in_group (rtx insn)
22598 enum attr_type type;
22601 || GET_CODE (insn) == NOTE
22602 || DEBUG_INSN_P (insn)
22603 || GET_CODE (PATTERN (insn)) == USE
22604 || GET_CODE (PATTERN (insn)) == CLOBBER)
22607 switch (rs6000_cpu)
22609 case PROCESSOR_POWER5:
22610 if (is_cracked_insn (insn))
22612 case PROCESSOR_POWER4:
22613 if (is_microcoded_insn (insn))
22616 if (!rs6000_sched_groups)
22619 type = get_attr_type (insn);
22626 case TYPE_DELAYED_CR:
22627 case TYPE_CR_LOGICAL:
22641 case PROCESSOR_POWER6:
22642 type = get_attr_type (insn);
22646 case TYPE_INSERT_DWORD:
22650 case TYPE_VAR_SHIFT_ROTATE:
22657 case TYPE_INSERT_WORD:
22658 case TYPE_DELAYED_COMPARE:
22659 case TYPE_IMUL_COMPARE:
22660 case TYPE_LMUL_COMPARE:
22661 case TYPE_FPCOMPARE:
22672 case TYPE_LOAD_EXT_UX:
22674 case TYPE_STORE_UX:
22675 case TYPE_FPLOAD_U:
22676 case TYPE_FPLOAD_UX:
22677 case TYPE_FPSTORE_U:
22678 case TYPE_FPSTORE_UX:
22684 case PROCESSOR_POWER7:
22685 type = get_attr_type (insn);
22689 case TYPE_CR_LOGICAL:
22696 case TYPE_DELAYED_COMPARE:
22697 case TYPE_VAR_DELAYED_COMPARE:
22703 case TYPE_LOAD_EXT:
22704 case TYPE_LOAD_EXT_U:
22705 case TYPE_LOAD_EXT_UX:
22707 case TYPE_STORE_UX:
22708 case TYPE_FPLOAD_U:
22709 case TYPE_FPLOAD_UX:
22710 case TYPE_FPSTORE_U:
22711 case TYPE_FPSTORE_UX:
22727 insn_must_be_last_in_group (rtx insn)
22729 enum attr_type type;
22732 || GET_CODE (insn) == NOTE
22733 || DEBUG_INSN_P (insn)
22734 || GET_CODE (PATTERN (insn)) == USE
22735 || GET_CODE (PATTERN (insn)) == CLOBBER)
22738 switch (rs6000_cpu) {
22739 case PROCESSOR_POWER4:
22740 case PROCESSOR_POWER5:
22741 if (is_microcoded_insn (insn))
22744 if (is_branch_slot_insn (insn))
22748 case PROCESSOR_POWER6:
22749 type = get_attr_type (insn);
22756 case TYPE_VAR_SHIFT_ROTATE:
22763 case TYPE_DELAYED_COMPARE:
22764 case TYPE_IMUL_COMPARE:
22765 case TYPE_LMUL_COMPARE:
22766 case TYPE_FPCOMPARE:
22780 case PROCESSOR_POWER7:
22781 type = get_attr_type (insn);
22789 case TYPE_LOAD_EXT_U:
22790 case TYPE_LOAD_EXT_UX:
22791 case TYPE_STORE_UX:
22804 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22805 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22808 is_costly_group (rtx *group_insns, rtx next_insn)
22811 int issue_rate = rs6000_issue_rate ();
22813 for (i = 0; i < issue_rate; i++)
22815 sd_iterator_def sd_it;
22817 rtx insn = group_insns[i];
22822 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22824 rtx next = DEP_CON (dep);
22826 if (next == next_insn
22827 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22835 /* Utility of the function redefine_groups.
22836 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22837 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22838 to keep it "far" (in a separate group) from GROUP_INSNS, following
22839 one of the following schemes, depending on the value of the flag
22840 -minsert_sched_nops = X:
22841 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22842 in order to force NEXT_INSN into a separate group.
22843 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22844 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22845 insertion (has a group just ended, how many vacant issue slots remain in the
22846 last group, and how many dispatch groups were encountered so far). */
22849 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22850 rtx next_insn, bool *group_end, int can_issue_more,
22855 int issue_rate = rs6000_issue_rate ();
22856 bool end = *group_end;
22859 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22860 return can_issue_more;
22862 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22863 return can_issue_more;
22865 force = is_costly_group (group_insns, next_insn);
22867 return can_issue_more;
22869 if (sched_verbose > 6)
22870 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22871 *group_count ,can_issue_more);
22873 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22876 can_issue_more = 0;
22878 /* Since only a branch can be issued in the last issue_slot, it is
22879 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22880 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22881 in this case the last nop will start a new group and the branch
22882 will be forced to the new group. */
22883 if (can_issue_more && !is_branch_slot_insn (next_insn))
22886 while (can_issue_more > 0)
22889 emit_insn_before (nop, next_insn);
22897 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22899 int n_nops = rs6000_sched_insert_nops;
22901 /* Nops can't be issued from the branch slot, so the effective
22902 issue_rate for nops is 'issue_rate - 1'. */
22903 if (can_issue_more == 0)
22904 can_issue_more = issue_rate;
22906 if (can_issue_more == 0)
22908 can_issue_more = issue_rate - 1;
22911 for (i = 0; i < issue_rate; i++)
22913 group_insns[i] = 0;
22920 emit_insn_before (nop, next_insn);
22921 if (can_issue_more == issue_rate - 1) /* new group begins */
22924 if (can_issue_more == 0)
22926 can_issue_more = issue_rate - 1;
22929 for (i = 0; i < issue_rate; i++)
22931 group_insns[i] = 0;
22937 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22940 /* Is next_insn going to start a new group? */
22943 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22944 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22945 || (can_issue_more < issue_rate &&
22946 insn_terminates_group_p (next_insn, previous_group)));
22947 if (*group_end && end)
22950 if (sched_verbose > 6)
22951 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22952 *group_count, can_issue_more);
22953 return can_issue_more;
22956 return can_issue_more;
22959 /* This function tries to synch the dispatch groups that the compiler "sees"
22960 with the dispatch groups that the processor dispatcher is expected to
22961 form in practice. It tries to achieve this synchronization by forcing the
22962 estimated processor grouping on the compiler (as opposed to the function
22963 'pad_goups' which tries to force the scheduler's grouping on the processor).
22965 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22966 examines the (estimated) dispatch groups that will be formed by the processor
22967 dispatcher. It marks these group boundaries to reflect the estimated
22968 processor grouping, overriding the grouping that the scheduler had marked.
22969 Depending on the value of the flag '-minsert-sched-nops' this function can
22970 force certain insns into separate groups or force a certain distance between
22971 them by inserting nops, for example, if there exists a "costly dependence"
22974 The function estimates the group boundaries that the processor will form as
22975 follows: It keeps track of how many vacant issue slots are available after
22976 each insn. A subsequent insn will start a new group if one of the following
22978 - no more vacant issue slots remain in the current dispatch group.
22979 - only the last issue slot, which is the branch slot, is vacant, but the next
22980 insn is not a branch.
22981 - only the last 2 or less issue slots, including the branch slot, are vacant,
22982 which means that a cracked insn (which occupies two issue slots) can't be
22983 issued in this group.
22984 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22985 start a new group. */
22988 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22990 rtx insn, next_insn;
22992 int can_issue_more;
22995 int group_count = 0;
22999 issue_rate = rs6000_issue_rate ();
23000 group_insns = XALLOCAVEC (rtx, issue_rate);
23001 for (i = 0; i < issue_rate; i++)
23003 group_insns[i] = 0;
23005 can_issue_more = issue_rate;
23007 insn = get_next_active_insn (prev_head_insn, tail);
23010 while (insn != NULL_RTX)
23012 slot = (issue_rate - can_issue_more);
23013 group_insns[slot] = insn;
23015 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23016 if (insn_terminates_group_p (insn, current_group))
23017 can_issue_more = 0;
23019 next_insn = get_next_active_insn (insn, tail);
23020 if (next_insn == NULL_RTX)
23021 return group_count + 1;
23023 /* Is next_insn going to start a new group? */
23025 = (can_issue_more == 0
23026 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23027 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23028 || (can_issue_more < issue_rate &&
23029 insn_terminates_group_p (next_insn, previous_group)));
23031 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23032 next_insn, &group_end, can_issue_more,
23038 can_issue_more = 0;
23039 for (i = 0; i < issue_rate; i++)
23041 group_insns[i] = 0;
23045 if (GET_MODE (next_insn) == TImode && can_issue_more)
23046 PUT_MODE (next_insn, VOIDmode);
23047 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23048 PUT_MODE (next_insn, TImode);
23051 if (can_issue_more == 0)
23052 can_issue_more = issue_rate;
23055 return group_count;
23058 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23059 dispatch group boundaries that the scheduler had marked. Pad with nops
23060 any dispatch groups which have vacant issue slots, in order to force the
23061 scheduler's grouping on the processor dispatcher. The function
23062 returns the number of dispatch groups found. */
23065 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23067 rtx insn, next_insn;
23070 int can_issue_more;
23072 int group_count = 0;
23074 /* Initialize issue_rate. */
23075 issue_rate = rs6000_issue_rate ();
23076 can_issue_more = issue_rate;
23078 insn = get_next_active_insn (prev_head_insn, tail);
23079 next_insn = get_next_active_insn (insn, tail);
23081 while (insn != NULL_RTX)
23084 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23086 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23088 if (next_insn == NULL_RTX)
23093 /* If the scheduler had marked group termination at this location
23094 (between insn and next_insn), and neither insn nor next_insn will
23095 force group termination, pad the group with nops to force group
23098 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23099 && !insn_terminates_group_p (insn, current_group)
23100 && !insn_terminates_group_p (next_insn, previous_group))
23102 if (!is_branch_slot_insn (next_insn))
23105 while (can_issue_more)
23108 emit_insn_before (nop, next_insn);
23113 can_issue_more = issue_rate;
23118 next_insn = get_next_active_insn (insn, tail);
23121 return group_count;
23124 /* We're beginning a new block. Initialize data structures as necessary. */
23127 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23128 int sched_verbose ATTRIBUTE_UNUSED,
23129 int max_ready ATTRIBUTE_UNUSED)
23131 last_scheduled_insn = NULL_RTX;
23132 load_store_pendulum = 0;
23135 /* The following function is called at the end of scheduling BB.
23136 After reload, it inserts nops at insn group bundling. */
23139 rs6000_sched_finish (FILE *dump, int sched_verbose)
23144 fprintf (dump, "=== Finishing schedule.\n");
23146 if (reload_completed && rs6000_sched_groups)
23148 /* Do not run sched_finish hook when selective scheduling enabled. */
23149 if (sel_sched_p ())
23152 if (rs6000_sched_insert_nops == sched_finish_none)
23155 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23156 n_groups = pad_groups (dump, sched_verbose,
23157 current_sched_info->prev_head,
23158 current_sched_info->next_tail);
23160 n_groups = redefine_groups (dump, sched_verbose,
23161 current_sched_info->prev_head,
23162 current_sched_info->next_tail);
23164 if (sched_verbose >= 6)
23166 fprintf (dump, "ngroups = %d\n", n_groups);
23167 print_rtl (dump, current_sched_info->prev_head);
23168 fprintf (dump, "Done finish_sched\n");
23173 struct _rs6000_sched_context
23175 short cached_can_issue_more;
23176 rtx last_scheduled_insn;
23177 int load_store_pendulum;
23180 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23181 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23183 /* Allocate store for new scheduling context. */
23185 rs6000_alloc_sched_context (void)
23187 return xmalloc (sizeof (rs6000_sched_context_def));
23190 /* If CLEAN_P is true then initializes _SC with clean data,
23191 and from the global context otherwise. */
23193 rs6000_init_sched_context (void *_sc, bool clean_p)
23195 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23199 sc->cached_can_issue_more = 0;
23200 sc->last_scheduled_insn = NULL_RTX;
23201 sc->load_store_pendulum = 0;
23205 sc->cached_can_issue_more = cached_can_issue_more;
23206 sc->last_scheduled_insn = last_scheduled_insn;
23207 sc->load_store_pendulum = load_store_pendulum;
23211 /* Sets the global scheduling context to the one pointed to by _SC. */
23213 rs6000_set_sched_context (void *_sc)
23215 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23217 gcc_assert (sc != NULL);
23219 cached_can_issue_more = sc->cached_can_issue_more;
23220 last_scheduled_insn = sc->last_scheduled_insn;
23221 load_store_pendulum = sc->load_store_pendulum;
23226 rs6000_free_sched_context (void *_sc)
23228 gcc_assert (_sc != NULL);
23234 /* Length in units of the trampoline for entering a nested function. */
23237 rs6000_trampoline_size (void)
23241 switch (DEFAULT_ABI)
23244 gcc_unreachable ();
23247 ret = (TARGET_32BIT) ? 12 : 24;
23252 ret = (TARGET_32BIT) ? 40 : 48;
23259 /* Emit RTL insns to initialize the variable parts of a trampoline.
23260 FNADDR is an RTX for the address of the function's pure code.
23261 CXT is an RTX for the static chain value for the function. */
23264 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23266 int regsize = (TARGET_32BIT) ? 4 : 8;
23267 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23268 rtx ctx_reg = force_reg (Pmode, cxt);
23269 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23271 switch (DEFAULT_ABI)
23274 gcc_unreachable ();
23276 /* Under AIX, just build the 3 word function descriptor */
23279 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23280 rtx fn_reg = gen_reg_rtx (Pmode);
23281 rtx toc_reg = gen_reg_rtx (Pmode);
23283 /* Macro to shorten the code expansions below. */
23284 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23286 m_tramp = replace_equiv_address (m_tramp, addr);
23288 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23289 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23290 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23291 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23292 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23298 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23301 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23302 LCT_NORMAL, VOIDmode, 4,
23304 GEN_INT (rs6000_trampoline_size ()), SImode,
23312 /* Handle the "altivec" attribute. The attribute may have
23313 arguments as follows:
23315 __attribute__((altivec(vector__)))
23316 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23317 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23319 and may appear more than once (e.g., 'vector bool char') in a
23320 given declaration. */
23323 rs6000_handle_altivec_attribute (tree *node,
23324 tree name ATTRIBUTE_UNUSED,
23326 int flags ATTRIBUTE_UNUSED,
23327 bool *no_add_attrs)
23329 tree type = *node, result = NULL_TREE;
23330 enum machine_mode mode;
23333 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23334 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23335 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23338 while (POINTER_TYPE_P (type)
23339 || TREE_CODE (type) == FUNCTION_TYPE
23340 || TREE_CODE (type) == METHOD_TYPE
23341 || TREE_CODE (type) == ARRAY_TYPE)
23342 type = TREE_TYPE (type);
23344 mode = TYPE_MODE (type);
23346 /* Check for invalid AltiVec type qualifiers. */
23347 if (type == long_double_type_node)
23348 error ("use of %<long double%> in AltiVec types is invalid");
23349 else if (type == boolean_type_node)
23350 error ("use of boolean types in AltiVec types is invalid");
23351 else if (TREE_CODE (type) == COMPLEX_TYPE)
23352 error ("use of %<complex%> in AltiVec types is invalid");
23353 else if (DECIMAL_FLOAT_MODE_P (mode))
23354 error ("use of decimal floating point types in AltiVec types is invalid");
23355 else if (!TARGET_VSX)
23357 if (type == long_unsigned_type_node || type == long_integer_type_node)
23360 error ("use of %<long%> in AltiVec types is invalid for "
23361 "64-bit code without -mvsx");
23362 else if (rs6000_warn_altivec_long)
23363 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23366 else if (type == long_long_unsigned_type_node
23367 || type == long_long_integer_type_node)
23368 error ("use of %<long long%> in AltiVec types is invalid without "
23370 else if (type == double_type_node)
23371 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23374 switch (altivec_type)
23377 unsigned_p = TYPE_UNSIGNED (type);
23381 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23384 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23387 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23390 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23392 case SFmode: result = V4SF_type_node; break;
23393 case DFmode: result = V2DF_type_node; break;
23394 /* If the user says 'vector int bool', we may be handed the 'bool'
23395 attribute _before_ the 'vector' attribute, and so select the
23396 proper type in the 'b' case below. */
23397 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23398 case V2DImode: case V2DFmode:
23406 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23407 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23408 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23409 case QImode: case V16QImode: result = bool_V16QI_type_node;
23416 case V8HImode: result = pixel_V8HI_type_node;
23422 /* Propagate qualifiers attached to the element type
23423 onto the vector type. */
23424 if (result && result != type && TYPE_QUALS (type))
23425 result = build_qualified_type (result, TYPE_QUALS (type));
23427 *no_add_attrs = true; /* No need to hang on to the attribute. */
23430 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23435 /* AltiVec defines four built-in scalar types that serve as vector
23436 elements; we must teach the compiler how to mangle them. */
23438 static const char *
23439 rs6000_mangle_type (const_tree type)
23441 type = TYPE_MAIN_VARIANT (type);
23443 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23444 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23447 if (type == bool_char_type_node) return "U6__boolc";
23448 if (type == bool_short_type_node) return "U6__bools";
23449 if (type == pixel_type_node) return "u7__pixel";
23450 if (type == bool_int_type_node) return "U6__booli";
23451 if (type == bool_long_type_node) return "U6__booll";
23453 /* Mangle IBM extended float long double as `g' (__float128) on
23454 powerpc*-linux where long-double-64 previously was the default. */
23455 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23457 && TARGET_LONG_DOUBLE_128
23458 && !TARGET_IEEEQUAD)
23461 /* For all other types, use normal C++ mangling. */
23465 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23466 struct attribute_spec.handler. */
23469 rs6000_handle_longcall_attribute (tree *node, tree name,
23470 tree args ATTRIBUTE_UNUSED,
23471 int flags ATTRIBUTE_UNUSED,
23472 bool *no_add_attrs)
23474 if (TREE_CODE (*node) != FUNCTION_TYPE
23475 && TREE_CODE (*node) != FIELD_DECL
23476 && TREE_CODE (*node) != TYPE_DECL)
23478 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23480 *no_add_attrs = true;
23486 /* Set longcall attributes on all functions declared when
23487 rs6000_default_long_calls is true. */
23489 rs6000_set_default_type_attributes (tree type)
23491 if (rs6000_default_long_calls
23492 && (TREE_CODE (type) == FUNCTION_TYPE
23493 || TREE_CODE (type) == METHOD_TYPE))
23494 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23496 TYPE_ATTRIBUTES (type));
23499 darwin_set_default_type_attributes (type);
23503 /* Return a reference suitable for calling a function with the
23504 longcall attribute. */
23507 rs6000_longcall_ref (rtx call_ref)
23509 const char *call_name;
23512 if (GET_CODE (call_ref) != SYMBOL_REF)
23515 /* System V adds '.' to the internal name, so skip them. */
23516 call_name = XSTR (call_ref, 0);
23517 if (*call_name == '.')
23519 while (*call_name == '.')
23522 node = get_identifier (call_name);
23523 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23526 return force_reg (Pmode, call_ref);
23529 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23530 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23533 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23534 struct attribute_spec.handler. */
23536 rs6000_handle_struct_attribute (tree *node, tree name,
23537 tree args ATTRIBUTE_UNUSED,
23538 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23541 if (DECL_P (*node))
23543 if (TREE_CODE (*node) == TYPE_DECL)
23544 type = &TREE_TYPE (*node);
23549 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23550 || TREE_CODE (*type) == UNION_TYPE)))
23552 warning (OPT_Wattributes, "%qE attribute ignored", name);
23553 *no_add_attrs = true;
23556 else if ((is_attribute_p ("ms_struct", name)
23557 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23558 || ((is_attribute_p ("gcc_struct", name)
23559 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23561 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23563 *no_add_attrs = true;
23570 rs6000_ms_bitfield_layout_p (const_tree record_type)
23572 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23573 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23574 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23577 #ifdef USING_ELFOS_H
23579 /* A get_unnamed_section callback, used for switching to toc_section. */
23582 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23584 if (DEFAULT_ABI == ABI_AIX
23585 && TARGET_MINIMAL_TOC
23586 && !TARGET_RELOCATABLE)
23588 if (!toc_initialized)
23590 toc_initialized = 1;
23591 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23592 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23593 fprintf (asm_out_file, "\t.tc ");
23594 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23595 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23596 fprintf (asm_out_file, "\n");
23598 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23599 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23600 fprintf (asm_out_file, " = .+32768\n");
23603 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23605 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23606 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23609 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23610 if (!toc_initialized)
23612 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23613 fprintf (asm_out_file, " = .+32768\n");
23614 toc_initialized = 1;
23619 /* Implement TARGET_ASM_INIT_SECTIONS. */
23622 rs6000_elf_asm_init_sections (void)
23625 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23628 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23629 SDATA2_SECTION_ASM_OP);
23632 /* Implement TARGET_SELECT_RTX_SECTION. */
23635 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23636 unsigned HOST_WIDE_INT align)
23638 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23639 return toc_section;
23641 return default_elf_select_rtx_section (mode, x, align);
23644 /* For a SYMBOL_REF, set generic flags and then perform some
23645 target-specific processing.
23647 When the AIX ABI is requested on a non-AIX system, replace the
23648 function name with the real name (with a leading .) rather than the
23649 function descriptor name. This saves a lot of overriding code to
23650 read the prefixes. */
23653 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23655 default_encode_section_info (decl, rtl, first);
23658 && TREE_CODE (decl) == FUNCTION_DECL
23660 && DEFAULT_ABI == ABI_AIX)
23662 rtx sym_ref = XEXP (rtl, 0);
23663 size_t len = strlen (XSTR (sym_ref, 0));
23664 char *str = XALLOCAVEC (char, len + 2);
23666 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23667 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23672 compare_section_name (const char *section, const char *templ)
23676 len = strlen (templ);
23677 return (strncmp (section, templ, len) == 0
23678 && (section[len] == 0 || section[len] == '.'));
23682 rs6000_elf_in_small_data_p (const_tree decl)
23684 if (rs6000_sdata == SDATA_NONE)
23687 /* We want to merge strings, so we never consider them small data. */
23688 if (TREE_CODE (decl) == STRING_CST)
23691 /* Functions are never in the small data area. */
23692 if (TREE_CODE (decl) == FUNCTION_DECL)
23695 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23697 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23698 if (compare_section_name (section, ".sdata")
23699 || compare_section_name (section, ".sdata2")
23700 || compare_section_name (section, ".gnu.linkonce.s")
23701 || compare_section_name (section, ".sbss")
23702 || compare_section_name (section, ".sbss2")
23703 || compare_section_name (section, ".gnu.linkonce.sb")
23704 || strcmp (section, ".PPC.EMB.sdata0") == 0
23705 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23710 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23713 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23714 /* If it's not public, and we're not going to reference it there,
23715 there's no need to put it in the small data section. */
23716 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23723 #endif /* USING_ELFOS_H */
23725 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23728 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23730 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23733 /* Return a REG that occurs in ADDR with coefficient 1.
23734 ADDR can be effectively incremented by incrementing REG.
23736 r0 is special and we must not select it as an address
23737 register by this routine since our caller will try to
23738 increment the returned register via an "la" instruction. */
23741 find_addr_reg (rtx addr)
23743 while (GET_CODE (addr) == PLUS)
23745 if (GET_CODE (XEXP (addr, 0)) == REG
23746 && REGNO (XEXP (addr, 0)) != 0)
23747 addr = XEXP (addr, 0);
23748 else if (GET_CODE (XEXP (addr, 1)) == REG
23749 && REGNO (XEXP (addr, 1)) != 0)
23750 addr = XEXP (addr, 1);
23751 else if (CONSTANT_P (XEXP (addr, 0)))
23752 addr = XEXP (addr, 1);
23753 else if (CONSTANT_P (XEXP (addr, 1)))
23754 addr = XEXP (addr, 0);
23756 gcc_unreachable ();
23758 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23763 rs6000_fatal_bad_address (rtx op)
23765 fatal_insn ("bad address", op);
23770 static tree branch_island_list = 0;
23772 /* Remember to generate a branch island for far calls to the given
23776 add_compiler_branch_island (tree label_name, tree function_name,
23779 tree branch_island = build_tree_list (function_name, label_name);
23780 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23781 TREE_CHAIN (branch_island) = branch_island_list;
23782 branch_island_list = branch_island;
23785 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23786 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23787 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23788 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23790 /* Generate far-jump branch islands for everything on the
23791 branch_island_list. Invoked immediately after the last instruction
23792 of the epilogue has been emitted; the branch-islands must be
23793 appended to, and contiguous with, the function body. Mach-O stubs
23794 are generated in machopic_output_stub(). */
23797 macho_branch_islands (void)
23800 tree branch_island;
23802 for (branch_island = branch_island_list;
23804 branch_island = TREE_CHAIN (branch_island))
23806 const char *label =
23807 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23809 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23810 char name_buf[512];
23811 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23812 if (name[0] == '*' || name[0] == '&')
23813 strcpy (name_buf, name+1);
23817 strcpy (name_buf+1, name);
23819 strcpy (tmp_buf, "\n");
23820 strcat (tmp_buf, label);
23821 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23822 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23823 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23824 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23827 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23828 strcat (tmp_buf, label);
23829 strcat (tmp_buf, "_pic\n");
23830 strcat (tmp_buf, label);
23831 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23833 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23834 strcat (tmp_buf, name_buf);
23835 strcat (tmp_buf, " - ");
23836 strcat (tmp_buf, label);
23837 strcat (tmp_buf, "_pic)\n");
23839 strcat (tmp_buf, "\tmtlr r0\n");
23841 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23842 strcat (tmp_buf, name_buf);
23843 strcat (tmp_buf, " - ");
23844 strcat (tmp_buf, label);
23845 strcat (tmp_buf, "_pic)\n");
23847 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23851 strcat (tmp_buf, ":\nlis r12,hi16(");
23852 strcat (tmp_buf, name_buf);
23853 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23854 strcat (tmp_buf, name_buf);
23855 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23857 output_asm_insn (tmp_buf, 0);
23858 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23859 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23860 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23861 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23864 branch_island_list = 0;
23867 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23868 already there or not. */
23871 no_previous_def (tree function_name)
23873 tree branch_island;
23874 for (branch_island = branch_island_list;
23876 branch_island = TREE_CHAIN (branch_island))
23877 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23882 /* GET_PREV_LABEL gets the label name from the previous definition of
23886 get_prev_label (tree function_name)
23888 tree branch_island;
23889 for (branch_island = branch_island_list;
23891 branch_island = TREE_CHAIN (branch_island))
23892 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23893 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23897 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23898 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23901 /* KEXTs still need branch islands. */
23902 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23903 || flag_mkernel || flag_apple_kext)
23905 /* INSN is either a function call or a millicode call. It may have an
23906 unconditional jump in its delay slot.
23908 CALL_DEST is the routine we are calling. */
23911 output_call (rtx insn, rtx *operands, int dest_operand_number,
23912 int cookie_operand_number)
23914 static char buf[256];
23915 if (DARWIN_GENERATE_ISLANDS
23916 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23917 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23920 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23922 if (no_previous_def (funname))
23924 rtx label_rtx = gen_label_rtx ();
23925 char *label_buf, temp_buf[256];
23926 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23927 CODE_LABEL_NUMBER (label_rtx));
23928 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23929 labelname = get_identifier (label_buf);
23930 add_compiler_branch_island (labelname, funname, insn_line (insn));
23933 labelname = get_prev_label (funname);
23935 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23936 instruction will reach 'foo', otherwise link as 'bl L42'".
23937 "L42" should be a 'branch island', that will do a far jump to
23938 'foo'. Branch islands are generated in
23939 macho_branch_islands(). */
23940 sprintf (buf, "jbsr %%z%d,%.246s",
23941 dest_operand_number, IDENTIFIER_POINTER (labelname));
23944 sprintf (buf, "bl %%z%d", dest_operand_number);
23948 /* Generate PIC and indirect symbol stubs. */
23951 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23953 unsigned int length;
23954 char *symbol_name, *lazy_ptr_name;
23955 char *local_label_0;
23956 static int label = 0;
23958 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23959 symb = (*targetm.strip_name_encoding) (symb);
23962 length = strlen (symb);
23963 symbol_name = XALLOCAVEC (char, length + 32);
23964 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23966 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23967 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23970 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23972 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23976 fprintf (file, "\t.align 5\n");
23978 fprintf (file, "%s:\n", stub);
23979 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23982 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23983 sprintf (local_label_0, "\"L%011d$spb\"", label);
23985 fprintf (file, "\tmflr r0\n");
23986 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23987 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23988 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23989 lazy_ptr_name, local_label_0);
23990 fprintf (file, "\tmtlr r0\n");
23991 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23992 (TARGET_64BIT ? "ldu" : "lwzu"),
23993 lazy_ptr_name, local_label_0);
23994 fprintf (file, "\tmtctr r12\n");
23995 fprintf (file, "\tbctr\n");
23999 fprintf (file, "\t.align 4\n");
24001 fprintf (file, "%s:\n", stub);
24002 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24004 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24005 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24006 (TARGET_64BIT ? "ldu" : "lwzu"),
24008 fprintf (file, "\tmtctr r12\n");
24009 fprintf (file, "\tbctr\n");
24012 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24013 fprintf (file, "%s:\n", lazy_ptr_name);
24014 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24015 fprintf (file, "%sdyld_stub_binding_helper\n",
24016 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24019 /* Legitimize PIC addresses. If the address is already
24020 position-independent, we return ORIG. Newly generated
24021 position-independent addresses go into a reg. This is REG if non
24022 zero, otherwise we allocate register(s) as necessary. */
24024 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24027 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24032 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24033 reg = gen_reg_rtx (Pmode);
24035 if (GET_CODE (orig) == CONST)
24039 if (GET_CODE (XEXP (orig, 0)) == PLUS
24040 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24043 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24045 /* Use a different reg for the intermediate value, as
24046 it will be marked UNCHANGING. */
24047 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24048 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24051 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24054 if (GET_CODE (offset) == CONST_INT)
24056 if (SMALL_INT (offset))
24057 return plus_constant (base, INTVAL (offset));
24058 else if (! reload_in_progress && ! reload_completed)
24059 offset = force_reg (Pmode, offset);
24062 rtx mem = force_const_mem (Pmode, orig);
24063 return machopic_legitimize_pic_address (mem, Pmode, reg);
24066 return gen_rtx_PLUS (Pmode, base, offset);
24069 /* Fall back on generic machopic code. */
24070 return machopic_legitimize_pic_address (orig, mode, reg);
24073 /* Output a .machine directive for the Darwin assembler, and call
24074 the generic start_file routine. */
24077 rs6000_darwin_file_start (void)
24079 static const struct
24085 { "ppc64", "ppc64", MASK_64BIT },
24086 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24087 { "power4", "ppc970", 0 },
24088 { "G5", "ppc970", 0 },
24089 { "7450", "ppc7450", 0 },
24090 { "7400", "ppc7400", MASK_ALTIVEC },
24091 { "G4", "ppc7400", 0 },
24092 { "750", "ppc750", 0 },
24093 { "740", "ppc750", 0 },
24094 { "G3", "ppc750", 0 },
24095 { "604e", "ppc604e", 0 },
24096 { "604", "ppc604", 0 },
24097 { "603e", "ppc603", 0 },
24098 { "603", "ppc603", 0 },
24099 { "601", "ppc601", 0 },
24100 { NULL, "ppc", 0 } };
24101 const char *cpu_id = "";
24104 rs6000_file_start ();
24105 darwin_file_start ();
24107 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24108 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24109 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24110 && rs6000_select[i].string[0] != '\0')
24111 cpu_id = rs6000_select[i].string;
24113 /* Look through the mapping array. Pick the first name that either
24114 matches the argument, has a bit set in IF_SET that is also set
24115 in the target flags, or has a NULL name. */
24118 while (mapping[i].arg != NULL
24119 && strcmp (mapping[i].arg, cpu_id) != 0
24120 && (mapping[i].if_set & target_flags) == 0)
24123 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24126 #endif /* TARGET_MACHO */
24130 rs6000_elf_reloc_rw_mask (void)
24134 else if (DEFAULT_ABI == ABI_AIX)
24140 /* Record an element in the table of global constructors. SYMBOL is
24141 a SYMBOL_REF of the function to be called; PRIORITY is a number
24142 between 0 and MAX_INIT_PRIORITY.
24144 This differs from default_named_section_asm_out_constructor in
24145 that we have special handling for -mrelocatable. */
24148 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24150 const char *section = ".ctors";
24153 if (priority != DEFAULT_INIT_PRIORITY)
24155 sprintf (buf, ".ctors.%.5u",
24156 /* Invert the numbering so the linker puts us in the proper
24157 order; constructors are run from right to left, and the
24158 linker sorts in increasing order. */
24159 MAX_INIT_PRIORITY - priority);
24163 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24164 assemble_align (POINTER_SIZE);
24166 if (TARGET_RELOCATABLE)
24168 fputs ("\t.long (", asm_out_file);
24169 output_addr_const (asm_out_file, symbol);
24170 fputs (")@fixup\n", asm_out_file);
24173 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24177 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24179 const char *section = ".dtors";
24182 if (priority != DEFAULT_INIT_PRIORITY)
24184 sprintf (buf, ".dtors.%.5u",
24185 /* Invert the numbering so the linker puts us in the proper
24186 order; constructors are run from right to left, and the
24187 linker sorts in increasing order. */
24188 MAX_INIT_PRIORITY - priority);
24192 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24193 assemble_align (POINTER_SIZE);
24195 if (TARGET_RELOCATABLE)
24197 fputs ("\t.long (", asm_out_file);
24198 output_addr_const (asm_out_file, symbol);
24199 fputs (")@fixup\n", asm_out_file);
24202 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24206 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24210 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24211 ASM_OUTPUT_LABEL (file, name);
24212 fputs (DOUBLE_INT_ASM_OP, file);
24213 rs6000_output_function_entry (file, name);
24214 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24217 fputs ("\t.size\t", file);
24218 assemble_name (file, name);
24219 fputs (",24\n\t.type\t.", file);
24220 assemble_name (file, name);
24221 fputs (",@function\n", file);
24222 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24224 fputs ("\t.globl\t.", file);
24225 assemble_name (file, name);
24230 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24231 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24232 rs6000_output_function_entry (file, name);
24233 fputs (":\n", file);
24237 if (TARGET_RELOCATABLE
24238 && !TARGET_SECURE_PLT
24239 && (get_pool_size () != 0 || crtl->profile)
24244 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24246 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24247 fprintf (file, "\t.long ");
24248 assemble_name (file, buf);
24250 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24251 assemble_name (file, buf);
24255 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24256 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24258 if (DEFAULT_ABI == ABI_AIX)
24260 const char *desc_name, *orig_name;
24262 orig_name = (*targetm.strip_name_encoding) (name);
24263 desc_name = orig_name;
24264 while (*desc_name == '.')
24267 if (TREE_PUBLIC (decl))
24268 fprintf (file, "\t.globl %s\n", desc_name);
24270 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24271 fprintf (file, "%s:\n", desc_name);
24272 fprintf (file, "\t.long %s\n", orig_name);
24273 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24274 if (DEFAULT_ABI == ABI_AIX)
24275 fputs ("\t.long 0\n", file);
24276 fprintf (file, "\t.previous\n");
24278 ASM_OUTPUT_LABEL (file, name);
24282 rs6000_elf_end_indicate_exec_stack (void)
24285 file_end_indicate_exec_stack ();
24291 rs6000_xcoff_asm_output_anchor (rtx symbol)
24295 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24296 SYMBOL_REF_BLOCK_OFFSET (symbol));
24297 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24301 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24303 fputs (GLOBAL_ASM_OP, stream);
24304 RS6000_OUTPUT_BASENAME (stream, name);
24305 putc ('\n', stream);
24308 /* A get_unnamed_decl callback, used for read-only sections. PTR
24309 points to the section string variable. */
24312 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24314 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24315 *(const char *const *) directive,
24316 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24319 /* Likewise for read-write sections. */
24322 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24324 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24325 *(const char *const *) directive,
24326 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24329 /* A get_unnamed_section callback, used for switching to toc_section. */
24332 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24334 if (TARGET_MINIMAL_TOC)
24336 /* toc_section is always selected at least once from
24337 rs6000_xcoff_file_start, so this is guaranteed to
24338 always be defined once and only once in each file. */
24339 if (!toc_initialized)
24341 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24342 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24343 toc_initialized = 1;
24345 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24346 (TARGET_32BIT ? "" : ",3"));
24349 fputs ("\t.toc\n", asm_out_file);
24352 /* Implement TARGET_ASM_INIT_SECTIONS. */
24355 rs6000_xcoff_asm_init_sections (void)
24357 read_only_data_section
24358 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24359 &xcoff_read_only_section_name);
24361 private_data_section
24362 = get_unnamed_section (SECTION_WRITE,
24363 rs6000_xcoff_output_readwrite_section_asm_op,
24364 &xcoff_private_data_section_name);
24366 read_only_private_data_section
24367 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24368 &xcoff_private_data_section_name);
24371 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24373 readonly_data_section = read_only_data_section;
24374 exception_section = data_section;
24378 rs6000_xcoff_reloc_rw_mask (void)
24384 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24385 tree decl ATTRIBUTE_UNUSED)
24388 static const char * const suffix[3] = { "PR", "RO", "RW" };
24390 if (flags & SECTION_CODE)
24392 else if (flags & SECTION_WRITE)
24397 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24398 (flags & SECTION_CODE) ? "." : "",
24399 name, suffix[smclass], flags & SECTION_ENTSIZE);
24403 rs6000_xcoff_select_section (tree decl, int reloc,
24404 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24406 if (decl_readonly_section (decl, reloc))
24408 if (TREE_PUBLIC (decl))
24409 return read_only_data_section;
24411 return read_only_private_data_section;
24415 if (TREE_PUBLIC (decl))
24416 return data_section;
24418 return private_data_section;
24423 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24427 /* Use select_section for private and uninitialized data. */
24428 if (!TREE_PUBLIC (decl)
24429 || DECL_COMMON (decl)
24430 || DECL_INITIAL (decl) == NULL_TREE
24431 || DECL_INITIAL (decl) == error_mark_node
24432 || (flag_zero_initialized_in_bss
24433 && initializer_zerop (DECL_INITIAL (decl))))
24436 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24437 name = (*targetm.strip_name_encoding) (name);
24438 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24441 /* Select section for constant in constant pool.
24443 On RS/6000, all constants are in the private read-only data area.
24444 However, if this is being placed in the TOC it must be output as a
24448 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24449 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24451 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24452 return toc_section;
24454 return read_only_private_data_section;
24457 /* Remove any trailing [DS] or the like from the symbol name. */
24459 static const char *
24460 rs6000_xcoff_strip_name_encoding (const char *name)
24465 len = strlen (name);
24466 if (name[len - 1] == ']')
24467 return ggc_alloc_string (name, len - 4);
24472 /* Section attributes. AIX is always PIC. */
24474 static unsigned int
24475 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24477 unsigned int align;
24478 unsigned int flags = default_section_type_flags (decl, name, reloc);
24480 /* Align to at least UNIT size. */
24481 if (flags & SECTION_CODE)
24482 align = MIN_UNITS_PER_WORD;
24484 /* Increase alignment of large objects if not already stricter. */
24485 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24486 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24487 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24489 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24492 /* Output at beginning of assembler file.
24494 Initialize the section names for the RS/6000 at this point.
24496 Specify filename, including full path, to assembler.
24498 We want to go into the TOC section so at least one .toc will be emitted.
24499 Also, in order to output proper .bs/.es pairs, we need at least one static
24500 [RW] section emitted.
24502 Finally, declare mcount when profiling to make the assembler happy. */
24505 rs6000_xcoff_file_start (void)
24507 rs6000_gen_section_name (&xcoff_bss_section_name,
24508 main_input_filename, ".bss_");
24509 rs6000_gen_section_name (&xcoff_private_data_section_name,
24510 main_input_filename, ".rw_");
24511 rs6000_gen_section_name (&xcoff_read_only_section_name,
24512 main_input_filename, ".ro_");
24514 fputs ("\t.file\t", asm_out_file);
24515 output_quoted_string (asm_out_file, main_input_filename);
24516 fputc ('\n', asm_out_file);
24517 if (write_symbols != NO_DEBUG)
24518 switch_to_section (private_data_section);
24519 switch_to_section (text_section);
24521 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24522 rs6000_file_start ();
24525 /* Output at end of assembler file.
24526 On the RS/6000, referencing data should automatically pull in text. */
24529 rs6000_xcoff_file_end (void)
24531 switch_to_section (text_section);
24532 fputs ("_section_.text:\n", asm_out_file);
24533 switch_to_section (data_section);
24534 fputs (TARGET_32BIT
24535 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24538 #endif /* TARGET_XCOFF */
24540 /* Compute a (partial) cost for rtx X. Return true if the complete
24541 cost has been computed, and false if subexpressions should be
24542 scanned. In either case, *TOTAL contains the cost result. */
24545 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24548 enum machine_mode mode = GET_MODE (x);
24552 /* On the RS/6000, if it is valid in the insn, it is free. */
24554 if (((outer_code == SET
24555 || outer_code == PLUS
24556 || outer_code == MINUS)
24557 && (satisfies_constraint_I (x)
24558 || satisfies_constraint_L (x)))
24559 || (outer_code == AND
24560 && (satisfies_constraint_K (x)
24562 ? satisfies_constraint_L (x)
24563 : satisfies_constraint_J (x))
24564 || mask_operand (x, mode)
24566 && mask64_operand (x, DImode))))
24567 || ((outer_code == IOR || outer_code == XOR)
24568 && (satisfies_constraint_K (x)
24570 ? satisfies_constraint_L (x)
24571 : satisfies_constraint_J (x))))
24572 || outer_code == ASHIFT
24573 || outer_code == ASHIFTRT
24574 || outer_code == LSHIFTRT
24575 || outer_code == ROTATE
24576 || outer_code == ROTATERT
24577 || outer_code == ZERO_EXTRACT
24578 || (outer_code == MULT
24579 && satisfies_constraint_I (x))
24580 || ((outer_code == DIV || outer_code == UDIV
24581 || outer_code == MOD || outer_code == UMOD)
24582 && exact_log2 (INTVAL (x)) >= 0)
24583 || (outer_code == COMPARE
24584 && (satisfies_constraint_I (x)
24585 || satisfies_constraint_K (x)))
24586 || (outer_code == EQ
24587 && (satisfies_constraint_I (x)
24588 || satisfies_constraint_K (x)
24590 ? satisfies_constraint_L (x)
24591 : satisfies_constraint_J (x))))
24592 || (outer_code == GTU
24593 && satisfies_constraint_I (x))
24594 || (outer_code == LTU
24595 && satisfies_constraint_P (x)))
24600 else if ((outer_code == PLUS
24601 && reg_or_add_cint_operand (x, VOIDmode))
24602 || (outer_code == MINUS
24603 && reg_or_sub_cint_operand (x, VOIDmode))
24604 || ((outer_code == SET
24605 || outer_code == IOR
24606 || outer_code == XOR)
24608 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24610 *total = COSTS_N_INSNS (1);
24616 if (mode == DImode && code == CONST_DOUBLE)
24618 if ((outer_code == IOR || outer_code == XOR)
24619 && CONST_DOUBLE_HIGH (x) == 0
24620 && (CONST_DOUBLE_LOW (x)
24621 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24626 else if ((outer_code == AND && and64_2_operand (x, DImode))
24627 || ((outer_code == SET
24628 || outer_code == IOR
24629 || outer_code == XOR)
24630 && CONST_DOUBLE_HIGH (x) == 0))
24632 *total = COSTS_N_INSNS (1);
24642 /* When optimizing for size, MEM should be slightly more expensive
24643 than generating address, e.g., (plus (reg) (const)).
24644 L1 cache latency is about two instructions. */
24645 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24653 if (mode == DFmode)
24655 if (GET_CODE (XEXP (x, 0)) == MULT)
24657 /* FNMA accounted in outer NEG. */
24658 if (outer_code == NEG)
24659 *total = rs6000_cost->dmul - rs6000_cost->fp;
24661 *total = rs6000_cost->dmul;
24664 *total = rs6000_cost->fp;
24666 else if (mode == SFmode)
24668 /* FNMA accounted in outer NEG. */
24669 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24672 *total = rs6000_cost->fp;
24675 *total = COSTS_N_INSNS (1);
24679 if (mode == DFmode)
24681 if (GET_CODE (XEXP (x, 0)) == MULT
24682 || GET_CODE (XEXP (x, 1)) == MULT)
24684 /* FNMA accounted in outer NEG. */
24685 if (outer_code == NEG)
24686 *total = rs6000_cost->dmul - rs6000_cost->fp;
24688 *total = rs6000_cost->dmul;
24691 *total = rs6000_cost->fp;
24693 else if (mode == SFmode)
24695 /* FNMA accounted in outer NEG. */
24696 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24699 *total = rs6000_cost->fp;
24702 *total = COSTS_N_INSNS (1);
24706 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24707 && satisfies_constraint_I (XEXP (x, 1)))
24709 if (INTVAL (XEXP (x, 1)) >= -256
24710 && INTVAL (XEXP (x, 1)) <= 255)
24711 *total = rs6000_cost->mulsi_const9;
24713 *total = rs6000_cost->mulsi_const;
24715 /* FMA accounted in outer PLUS/MINUS. */
24716 else if ((mode == DFmode || mode == SFmode)
24717 && (outer_code == PLUS || outer_code == MINUS))
24719 else if (mode == DFmode)
24720 *total = rs6000_cost->dmul;
24721 else if (mode == SFmode)
24722 *total = rs6000_cost->fp;
24723 else if (mode == DImode)
24724 *total = rs6000_cost->muldi;
24726 *total = rs6000_cost->mulsi;
24731 if (FLOAT_MODE_P (mode))
24733 *total = mode == DFmode ? rs6000_cost->ddiv
24734 : rs6000_cost->sdiv;
24741 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24742 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24744 if (code == DIV || code == MOD)
24746 *total = COSTS_N_INSNS (2);
24749 *total = COSTS_N_INSNS (1);
24753 if (GET_MODE (XEXP (x, 1)) == DImode)
24754 *total = rs6000_cost->divdi;
24756 *total = rs6000_cost->divsi;
24758 /* Add in shift and subtract for MOD. */
24759 if (code == MOD || code == UMOD)
24760 *total += COSTS_N_INSNS (2);
24765 *total = COSTS_N_INSNS (4);
24769 *total = COSTS_N_INSNS (6);
24773 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24785 *total = COSTS_N_INSNS (1);
24793 /* Handle mul_highpart. */
24794 if (outer_code == TRUNCATE
24795 && GET_CODE (XEXP (x, 0)) == MULT)
24797 if (mode == DImode)
24798 *total = rs6000_cost->muldi;
24800 *total = rs6000_cost->mulsi;
24803 else if (outer_code == AND)
24806 *total = COSTS_N_INSNS (1);
24811 if (GET_CODE (XEXP (x, 0)) == MEM)
24814 *total = COSTS_N_INSNS (1);
24820 if (!FLOAT_MODE_P (mode))
24822 *total = COSTS_N_INSNS (1);
24828 case UNSIGNED_FLOAT:
24831 case FLOAT_TRUNCATE:
24832 *total = rs6000_cost->fp;
24836 if (mode == DFmode)
24839 *total = rs6000_cost->fp;
24843 switch (XINT (x, 1))
24846 *total = rs6000_cost->fp;
24858 *total = COSTS_N_INSNS (1);
24861 else if (FLOAT_MODE_P (mode)
24862 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24864 *total = rs6000_cost->fp;
24872 /* Carry bit requires mode == Pmode.
24873 NEG or PLUS already counted so only add one. */
24875 && (outer_code == NEG || outer_code == PLUS))
24877 *total = COSTS_N_INSNS (1);
24880 if (outer_code == SET)
24882 if (XEXP (x, 1) == const0_rtx)
24884 if (TARGET_ISEL && !TARGET_MFCRF)
24885 *total = COSTS_N_INSNS (8);
24887 *total = COSTS_N_INSNS (2);
24890 else if (mode == Pmode)
24892 *total = COSTS_N_INSNS (3);
24901 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24903 if (TARGET_ISEL && !TARGET_MFCRF)
24904 *total = COSTS_N_INSNS (8);
24906 *total = COSTS_N_INSNS (2);
24910 if (outer_code == COMPARE)
24924 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24927 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24930 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24933 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24934 "total = %d, speed = %s, x:\n",
24935 ret ? "complete" : "scan inner",
24936 GET_RTX_NAME (code),
24937 GET_RTX_NAME (outer_code),
24939 speed ? "true" : "false");
24946 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24949 rs6000_debug_address_cost (rtx x, bool speed)
24951 int ret = TARGET_ADDRESS_COST (x, speed);
24953 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24954 ret, speed ? "true" : "false");
24961 /* A C expression returning the cost of moving data from a register of class
24962 CLASS1 to one of CLASS2. */
24965 rs6000_register_move_cost (enum machine_mode mode,
24966 enum reg_class from, enum reg_class to)
24970 /* Moves from/to GENERAL_REGS. */
24971 if (reg_classes_intersect_p (to, GENERAL_REGS)
24972 || reg_classes_intersect_p (from, GENERAL_REGS))
24974 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24977 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24978 ret = (rs6000_memory_move_cost (mode, from, 0)
24979 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24981 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24983 else if (from == CR_REGS)
24986 /* Power6 has slower LR/CTR moves so make them more expensive than
24987 memory in order to bias spills to memory .*/
24988 else if (rs6000_cpu == PROCESSOR_POWER6
24989 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24990 ret = 6 * hard_regno_nregs[0][mode];
24993 /* A move will cost one instruction per GPR moved. */
24994 ret = 2 * hard_regno_nregs[0][mode];
24997 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24998 else if (VECTOR_UNIT_VSX_P (mode)
24999 && reg_classes_intersect_p (to, VSX_REGS)
25000 && reg_classes_intersect_p (from, VSX_REGS))
25001 ret = 2 * hard_regno_nregs[32][mode];
25003 /* Moving between two similar registers is just one instruction. */
25004 else if (reg_classes_intersect_p (to, from))
25005 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25007 /* Everything else has to go through GENERAL_REGS. */
25009 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25010 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25012 if (TARGET_DEBUG_COST)
25014 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25015 ret, GET_MODE_NAME (mode), reg_class_names[from],
25016 reg_class_names[to]);
25021 /* A C expressions returning the cost of moving data of MODE from a register to
25025 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25026 int in ATTRIBUTE_UNUSED)
25030 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25031 ret = 4 * hard_regno_nregs[0][mode];
25032 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25033 ret = 4 * hard_regno_nregs[32][mode];
25034 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25035 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25037 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25039 if (TARGET_DEBUG_COST)
25041 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25042 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25047 /* Returns a code for a target-specific builtin that implements
25048 reciprocal of the function, or NULL_TREE if not available. */
25051 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25052 bool sqrt ATTRIBUTE_UNUSED)
25054 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25055 && flag_finite_math_only && !flag_trapping_math
25056 && flag_unsafe_math_optimizations))
25064 case BUILT_IN_SQRTF:
25065 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25072 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25073 Assumes no trapping math and finite arguments. */
25076 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25078 rtx x0, e0, e1, y1, u0, v0, one;
25080 x0 = gen_reg_rtx (SFmode);
25081 e0 = gen_reg_rtx (SFmode);
25082 e1 = gen_reg_rtx (SFmode);
25083 y1 = gen_reg_rtx (SFmode);
25084 u0 = gen_reg_rtx (SFmode);
25085 v0 = gen_reg_rtx (SFmode);
25086 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25088 /* x0 = 1./d estimate */
25089 emit_insn (gen_rtx_SET (VOIDmode, x0,
25090 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25092 /* e0 = 1. - d * x0 */
25093 emit_insn (gen_rtx_SET (VOIDmode, e0,
25094 gen_rtx_MINUS (SFmode, one,
25095 gen_rtx_MULT (SFmode, d, x0))));
25096 /* e1 = e0 + e0 * e0 */
25097 emit_insn (gen_rtx_SET (VOIDmode, e1,
25098 gen_rtx_PLUS (SFmode,
25099 gen_rtx_MULT (SFmode, e0, e0), e0)));
25100 /* y1 = x0 + e1 * x0 */
25101 emit_insn (gen_rtx_SET (VOIDmode, y1,
25102 gen_rtx_PLUS (SFmode,
25103 gen_rtx_MULT (SFmode, e1, x0), x0)));
25105 emit_insn (gen_rtx_SET (VOIDmode, u0,
25106 gen_rtx_MULT (SFmode, n, y1)));
25107 /* v0 = n - d * u0 */
25108 emit_insn (gen_rtx_SET (VOIDmode, v0,
25109 gen_rtx_MINUS (SFmode, n,
25110 gen_rtx_MULT (SFmode, d, u0))));
25111 /* dst = u0 + v0 * y1 */
25112 emit_insn (gen_rtx_SET (VOIDmode, dst,
25113 gen_rtx_PLUS (SFmode,
25114 gen_rtx_MULT (SFmode, v0, y1), u0)));
25117 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25118 Assumes no trapping math and finite arguments. */
25121 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25123 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25125 x0 = gen_reg_rtx (DFmode);
25126 e0 = gen_reg_rtx (DFmode);
25127 e1 = gen_reg_rtx (DFmode);
25128 e2 = gen_reg_rtx (DFmode);
25129 y1 = gen_reg_rtx (DFmode);
25130 y2 = gen_reg_rtx (DFmode);
25131 y3 = gen_reg_rtx (DFmode);
25132 u0 = gen_reg_rtx (DFmode);
25133 v0 = gen_reg_rtx (DFmode);
25134 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25136 /* x0 = 1./d estimate */
25137 emit_insn (gen_rtx_SET (VOIDmode, x0,
25138 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25140 /* e0 = 1. - d * x0 */
25141 emit_insn (gen_rtx_SET (VOIDmode, e0,
25142 gen_rtx_MINUS (DFmode, one,
25143 gen_rtx_MULT (SFmode, d, x0))));
25144 /* y1 = x0 + e0 * x0 */
25145 emit_insn (gen_rtx_SET (VOIDmode, y1,
25146 gen_rtx_PLUS (DFmode,
25147 gen_rtx_MULT (DFmode, e0, x0), x0)));
25149 emit_insn (gen_rtx_SET (VOIDmode, e1,
25150 gen_rtx_MULT (DFmode, e0, e0)));
25151 /* y2 = y1 + e1 * y1 */
25152 emit_insn (gen_rtx_SET (VOIDmode, y2,
25153 gen_rtx_PLUS (DFmode,
25154 gen_rtx_MULT (DFmode, e1, y1), y1)));
25156 emit_insn (gen_rtx_SET (VOIDmode, e2,
25157 gen_rtx_MULT (DFmode, e1, e1)));
25158 /* y3 = y2 + e2 * y2 */
25159 emit_insn (gen_rtx_SET (VOIDmode, y3,
25160 gen_rtx_PLUS (DFmode,
25161 gen_rtx_MULT (DFmode, e2, y2), y2)));
25163 emit_insn (gen_rtx_SET (VOIDmode, u0,
25164 gen_rtx_MULT (DFmode, n, y3)));
25165 /* v0 = n - d * u0 */
25166 emit_insn (gen_rtx_SET (VOIDmode, v0,
25167 gen_rtx_MINUS (DFmode, n,
25168 gen_rtx_MULT (DFmode, d, u0))));
25169 /* dst = u0 + v0 * y3 */
25170 emit_insn (gen_rtx_SET (VOIDmode, dst,
25171 gen_rtx_PLUS (DFmode,
25172 gen_rtx_MULT (DFmode, v0, y3), u0)));
25176 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25177 Assumes no trapping math and finite arguments. */
25180 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25182 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25183 half, one, halfthree, c1, cond, label;
25185 x0 = gen_reg_rtx (SFmode);
25186 x1 = gen_reg_rtx (SFmode);
25187 x2 = gen_reg_rtx (SFmode);
25188 y1 = gen_reg_rtx (SFmode);
25189 u0 = gen_reg_rtx (SFmode);
25190 u1 = gen_reg_rtx (SFmode);
25191 u2 = gen_reg_rtx (SFmode);
25192 v0 = gen_reg_rtx (SFmode);
25193 v1 = gen_reg_rtx (SFmode);
25194 v2 = gen_reg_rtx (SFmode);
25195 t0 = gen_reg_rtx (SFmode);
25196 halfthree = gen_reg_rtx (SFmode);
25197 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25198 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25200 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25201 emit_insn (gen_rtx_SET (VOIDmode, t0,
25202 gen_rtx_MULT (SFmode, src, src)));
25204 emit_insn (gen_rtx_SET (VOIDmode, cond,
25205 gen_rtx_COMPARE (CCFPmode, t0, src)));
25206 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25207 emit_unlikely_jump (c1, label);
25209 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25210 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25212 /* halfthree = 1.5 = 1.0 + 0.5 */
25213 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25214 gen_rtx_PLUS (SFmode, one, half)));
25216 /* x0 = rsqrt estimate */
25217 emit_insn (gen_rtx_SET (VOIDmode, x0,
25218 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25221 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25222 emit_insn (gen_rtx_SET (VOIDmode, y1,
25223 gen_rtx_MINUS (SFmode,
25224 gen_rtx_MULT (SFmode, src, halfthree),
25227 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25228 emit_insn (gen_rtx_SET (VOIDmode, u0,
25229 gen_rtx_MULT (SFmode, x0, x0)));
25230 emit_insn (gen_rtx_SET (VOIDmode, v0,
25231 gen_rtx_MINUS (SFmode,
25233 gen_rtx_MULT (SFmode, y1, u0))));
25234 emit_insn (gen_rtx_SET (VOIDmode, x1,
25235 gen_rtx_MULT (SFmode, x0, v0)));
25237 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25238 emit_insn (gen_rtx_SET (VOIDmode, u1,
25239 gen_rtx_MULT (SFmode, x1, x1)));
25240 emit_insn (gen_rtx_SET (VOIDmode, v1,
25241 gen_rtx_MINUS (SFmode,
25243 gen_rtx_MULT (SFmode, y1, u1))));
25244 emit_insn (gen_rtx_SET (VOIDmode, x2,
25245 gen_rtx_MULT (SFmode, x1, v1)));
25247 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25248 emit_insn (gen_rtx_SET (VOIDmode, u2,
25249 gen_rtx_MULT (SFmode, x2, x2)));
25250 emit_insn (gen_rtx_SET (VOIDmode, v2,
25251 gen_rtx_MINUS (SFmode,
25253 gen_rtx_MULT (SFmode, y1, u2))));
25254 emit_insn (gen_rtx_SET (VOIDmode, dst,
25255 gen_rtx_MULT (SFmode, x2, v2)));
25257 emit_label (XEXP (label, 0));
25260 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25261 (Power7) targets. DST is the target, and SRC is the argument operand. */
25264 rs6000_emit_popcount (rtx dst, rtx src)
25266 enum machine_mode mode = GET_MODE (dst);
25269 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25270 if (TARGET_POPCNTD)
25272 if (mode == SImode)
25273 emit_insn (gen_popcntwsi2 (dst, src));
25275 emit_insn (gen_popcntddi2 (dst, src));
25279 tmp1 = gen_reg_rtx (mode);
25281 if (mode == SImode)
25283 emit_insn (gen_popcntbsi2 (tmp1, src));
25284 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25286 tmp2 = force_reg (SImode, tmp2);
25287 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25291 emit_insn (gen_popcntbdi2 (tmp1, src));
25292 tmp2 = expand_mult (DImode, tmp1,
25293 GEN_INT ((HOST_WIDE_INT)
25294 0x01010101 << 32 | 0x01010101),
25296 tmp2 = force_reg (DImode, tmp2);
25297 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25302 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25303 target, and SRC is the argument operand. */
25306 rs6000_emit_parity (rtx dst, rtx src)
25308 enum machine_mode mode = GET_MODE (dst);
25311 tmp = gen_reg_rtx (mode);
25312 if (mode == SImode)
25314 /* Is mult+shift >= shift+xor+shift+xor? */
25315 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25317 rtx tmp1, tmp2, tmp3, tmp4;
25319 tmp1 = gen_reg_rtx (SImode);
25320 emit_insn (gen_popcntbsi2 (tmp1, src));
25322 tmp2 = gen_reg_rtx (SImode);
25323 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25324 tmp3 = gen_reg_rtx (SImode);
25325 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25327 tmp4 = gen_reg_rtx (SImode);
25328 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25329 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25332 rs6000_emit_popcount (tmp, src);
25333 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25337 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25338 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25340 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25342 tmp1 = gen_reg_rtx (DImode);
25343 emit_insn (gen_popcntbdi2 (tmp1, src));
25345 tmp2 = gen_reg_rtx (DImode);
25346 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25347 tmp3 = gen_reg_rtx (DImode);
25348 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25350 tmp4 = gen_reg_rtx (DImode);
25351 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25352 tmp5 = gen_reg_rtx (DImode);
25353 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25355 tmp6 = gen_reg_rtx (DImode);
25356 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25357 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25360 rs6000_emit_popcount (tmp, src);
25361 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25365 /* Return an RTX representing where to find the function value of a
25366 function returning MODE. */
25368 rs6000_complex_function_value (enum machine_mode mode)
25370 unsigned int regno;
25372 enum machine_mode inner = GET_MODE_INNER (mode);
25373 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25375 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25376 regno = FP_ARG_RETURN;
25379 regno = GP_ARG_RETURN;
25381 /* 32-bit is OK since it'll go in r3/r4. */
25382 if (TARGET_32BIT && inner_bytes >= 4)
25383 return gen_rtx_REG (mode, regno);
25386 if (inner_bytes >= 8)
25387 return gen_rtx_REG (mode, regno);
25389 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25391 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25392 GEN_INT (inner_bytes));
25393 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25396 /* Target hook for TARGET_FUNCTION_VALUE.
25398 On the SPE, both FPs and vectors are returned in r3.
25400 On RS/6000 an integer value is in r3 and a floating-point value is in
25401 fp1, unless -msoft-float. */
25404 rs6000_function_value (const_tree valtype,
25405 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25406 bool outgoing ATTRIBUTE_UNUSED)
25408 enum machine_mode mode;
25409 unsigned int regno;
25411 /* Special handling for structs in darwin64. */
25412 if (rs6000_darwin64_abi
25413 && TYPE_MODE (valtype) == BLKmode
25414 && TREE_CODE (valtype) == RECORD_TYPE
25415 && int_size_in_bytes (valtype) > 0)
25417 CUMULATIVE_ARGS valcum;
25421 valcum.fregno = FP_ARG_MIN_REG;
25422 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25423 /* Do a trial code generation as if this were going to be passed as
25424 an argument; if any part goes in memory, we return NULL. */
25425 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25428 /* Otherwise fall through to standard ABI rules. */
25431 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25433 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25434 return gen_rtx_PARALLEL (DImode,
25436 gen_rtx_EXPR_LIST (VOIDmode,
25437 gen_rtx_REG (SImode, GP_ARG_RETURN),
25439 gen_rtx_EXPR_LIST (VOIDmode,
25440 gen_rtx_REG (SImode,
25441 GP_ARG_RETURN + 1),
25444 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25446 return gen_rtx_PARALLEL (DCmode,
25448 gen_rtx_EXPR_LIST (VOIDmode,
25449 gen_rtx_REG (SImode, GP_ARG_RETURN),
25451 gen_rtx_EXPR_LIST (VOIDmode,
25452 gen_rtx_REG (SImode,
25453 GP_ARG_RETURN + 1),
25455 gen_rtx_EXPR_LIST (VOIDmode,
25456 gen_rtx_REG (SImode,
25457 GP_ARG_RETURN + 2),
25459 gen_rtx_EXPR_LIST (VOIDmode,
25460 gen_rtx_REG (SImode,
25461 GP_ARG_RETURN + 3),
25465 mode = TYPE_MODE (valtype);
25466 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25467 || POINTER_TYPE_P (valtype))
25468 mode = TARGET_32BIT ? SImode : DImode;
25470 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25471 /* _Decimal128 must use an even/odd register pair. */
25472 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25473 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25474 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25475 regno = FP_ARG_RETURN;
25476 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25477 && targetm.calls.split_complex_arg)
25478 return rs6000_complex_function_value (mode);
25479 else if (TREE_CODE (valtype) == VECTOR_TYPE
25480 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25481 && ALTIVEC_VECTOR_MODE (mode))
25482 regno = ALTIVEC_ARG_RETURN;
25483 else if (TREE_CODE (valtype) == VECTOR_TYPE
25484 && TARGET_VSX && TARGET_ALTIVEC_ABI
25485 && VSX_VECTOR_MODE (mode))
25486 regno = ALTIVEC_ARG_RETURN;
25487 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25488 && (mode == DFmode || mode == DCmode
25489 || mode == TFmode || mode == TCmode))
25490 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25492 regno = GP_ARG_RETURN;
25494 return gen_rtx_REG (mode, regno);
25497 /* Define how to find the value returned by a library function
25498 assuming the value has mode MODE. */
25500 rs6000_libcall_value (enum machine_mode mode)
25502 unsigned int regno;
25504 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25506 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25507 return gen_rtx_PARALLEL (DImode,
25509 gen_rtx_EXPR_LIST (VOIDmode,
25510 gen_rtx_REG (SImode, GP_ARG_RETURN),
25512 gen_rtx_EXPR_LIST (VOIDmode,
25513 gen_rtx_REG (SImode,
25514 GP_ARG_RETURN + 1),
25518 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25519 /* _Decimal128 must use an even/odd register pair. */
25520 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25521 else if (SCALAR_FLOAT_MODE_P (mode)
25522 && TARGET_HARD_FLOAT && TARGET_FPRS
25523 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25524 regno = FP_ARG_RETURN;
25525 else if (ALTIVEC_VECTOR_MODE (mode)
25526 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25527 regno = ALTIVEC_ARG_RETURN;
25528 else if (VSX_VECTOR_MODE (mode)
25529 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25530 regno = ALTIVEC_ARG_RETURN;
25531 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25532 return rs6000_complex_function_value (mode);
25533 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25534 && (mode == DFmode || mode == DCmode
25535 || mode == TFmode || mode == TCmode))
25536 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25538 regno = GP_ARG_RETURN;
25540 return gen_rtx_REG (mode, regno);
25544 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25545 Frame pointer elimination is automatically handled.
25547 For the RS/6000, if frame pointer elimination is being done, we would like
25548 to convert ap into fp, not sp.
25550 We need r30 if -mminimal-toc was specified, and there are constant pool
25554 rs6000_can_eliminate (const int from, const int to)
25556 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25557 ? ! frame_pointer_needed
25558 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25559 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25563 /* Define the offset between two registers, FROM to be eliminated and its
25564 replacement TO, at the start of a routine. */
25566 rs6000_initial_elimination_offset (int from, int to)
25568 rs6000_stack_t *info = rs6000_stack_info ();
25569 HOST_WIDE_INT offset;
25571 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25572 offset = info->push_p ? 0 : -info->total_size;
25573 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25575 offset = info->push_p ? 0 : -info->total_size;
25576 if (FRAME_GROWS_DOWNWARD)
25577 offset += info->fixed_size + info->vars_size + info->parm_size;
25579 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25580 offset = FRAME_GROWS_DOWNWARD
25581 ? info->fixed_size + info->vars_size + info->parm_size
25583 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25584 offset = info->total_size;
25585 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25586 offset = info->push_p ? info->total_size : 0;
25587 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25590 gcc_unreachable ();
25596 rs6000_dwarf_register_span (rtx reg)
25600 unsigned regno = REGNO (reg);
25601 enum machine_mode mode = GET_MODE (reg);
25605 && (SPE_VECTOR_MODE (GET_MODE (reg))
25606 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25607 && mode != SFmode && mode != SDmode && mode != SCmode)))
25612 regno = REGNO (reg);
25614 /* The duality of the SPE register size wreaks all kinds of havoc.
25615 This is a way of distinguishing r0 in 32-bits from r0 in
25617 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25618 gcc_assert (words <= 4);
25619 for (i = 0; i < words; i++, regno++)
25621 if (BYTES_BIG_ENDIAN)
25623 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25624 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25628 parts[2 * i] = gen_rtx_REG (SImode, regno);
25629 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25633 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25636 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25639 rs6000_init_dwarf_reg_sizes_extra (tree address)
25644 enum machine_mode mode = TYPE_MODE (char_type_node);
25645 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25646 rtx mem = gen_rtx_MEM (BLKmode, addr);
25647 rtx value = gen_int_mode (4, mode);
25649 for (i = 1201; i < 1232; i++)
25651 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25652 HOST_WIDE_INT offset
25653 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25655 emit_move_insn (adjust_address (mem, mode, offset), value);
25660 /* Map internal gcc register numbers to DWARF2 register numbers. */
25663 rs6000_dbx_register_number (unsigned int regno)
25665 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25667 if (regno == MQ_REGNO)
25669 if (regno == LR_REGNO)
25671 if (regno == CTR_REGNO)
25673 if (CR_REGNO_P (regno))
25674 return regno - CR0_REGNO + 86;
25675 if (regno == XER_REGNO)
25677 if (ALTIVEC_REGNO_P (regno))
25678 return regno - FIRST_ALTIVEC_REGNO + 1124;
25679 if (regno == VRSAVE_REGNO)
25681 if (regno == VSCR_REGNO)
25683 if (regno == SPE_ACC_REGNO)
25685 if (regno == SPEFSCR_REGNO)
25687 /* SPE high reg number. We get these values of regno from
25688 rs6000_dwarf_register_span. */
25689 gcc_assert (regno >= 1200 && regno < 1232);
25693 /* target hook eh_return_filter_mode */
25694 static enum machine_mode
25695 rs6000_eh_return_filter_mode (void)
25697 return TARGET_32BIT ? SImode : word_mode;
25700 /* Target hook for scalar_mode_supported_p. */
25702 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25704 if (DECIMAL_FLOAT_MODE_P (mode))
25705 return default_decimal_float_supported_p ();
25707 return default_scalar_mode_supported_p (mode);
25710 /* Target hook for vector_mode_supported_p. */
25712 rs6000_vector_mode_supported_p (enum machine_mode mode)
25715 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25718 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25721 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25728 /* Target hook for invalid_arg_for_unprototyped_fn. */
25729 static const char *
25730 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25732 return (!rs6000_darwin64_abi
25734 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25735 && (funcdecl == NULL_TREE
25736 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25737 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25738 ? N_("AltiVec argument passed to unprototyped function")
25742 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25743 setup by using __stack_chk_fail_local hidden function instead of
25744 calling __stack_chk_fail directly. Otherwise it is better to call
25745 __stack_chk_fail directly. */
25748 rs6000_stack_protect_fail (void)
25750 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25751 ? default_hidden_stack_protect_fail ()
25752 : default_external_stack_protect_fail ();
25756 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25757 int num_operands ATTRIBUTE_UNUSED)
25759 if (rs6000_warn_cell_microcode)
25762 int insn_code_number = recog_memoized (insn);
25763 location_t location = locator_location (INSN_LOCATOR (insn));
25765 /* Punt on insns we cannot recognize. */
25766 if (insn_code_number < 0)
25769 temp = get_insn_template (insn_code_number, insn);
25771 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25772 warning_at (location, OPT_mwarn_cell_microcode,
25773 "emitting microcode insn %s\t[%s] #%d",
25774 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25775 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25776 warning_at (location, OPT_mwarn_cell_microcode,
25777 "emitting conditional microcode insn %s\t[%s] #%d",
25778 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25782 #include "gt-rs6000.h"