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 (tree, 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, 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. DEST_TYPE is the
2887 destination type and SRC_TYPE the source type of the conversion.
2888 Return NULL_TREE if it is not available. */
2890 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
2892 enum tree_code code = (enum tree_code) tcode;
2896 case FIX_TRUNC_EXPR:
2897 switch (TYPE_MODE (dest_type))
2900 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2903 return TYPE_UNSIGNED (dest_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 (dest_type)
2912 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2913 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2920 switch (TYPE_MODE (src_type))
2923 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2926 return TYPE_UNSIGNED (src_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 (src_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 (tree fndecl, tree type_out,
3185 enum machine_mode in_mode, out_mode;
3187 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3189 if (TREE_CODE (type_out) != VECTOR_TYPE
3190 || TREE_CODE (type_in) != VECTOR_TYPE
3191 || !TARGET_VECTORIZE_BUILTINS
3192 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
3195 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3196 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3197 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3198 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3202 case BUILT_IN_COPYSIGN:
3203 if (VECTOR_UNIT_VSX_P (V2DFmode)
3204 && out_mode == DFmode && out_n == 2
3205 && in_mode == DFmode && in_n == 2)
3206 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3208 case BUILT_IN_COPYSIGNF:
3209 if (out_mode != SFmode || out_n != 4
3210 || in_mode != SFmode || in_n != 4)
3212 if (VECTOR_UNIT_VSX_P (V4SFmode))
3213 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3214 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3215 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3218 if (VECTOR_UNIT_VSX_P (V2DFmode)
3219 && out_mode == DFmode && out_n == 2
3220 && in_mode == DFmode && in_n == 2)
3221 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3223 case BUILT_IN_SQRTF:
3224 if (VECTOR_UNIT_VSX_P (V4SFmode)
3225 && out_mode == SFmode && out_n == 4
3226 && in_mode == SFmode && in_n == 4)
3227 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3230 if (VECTOR_UNIT_VSX_P (V2DFmode)
3231 && out_mode == DFmode && out_n == 2
3232 && in_mode == DFmode && in_n == 2)
3233 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3235 case BUILT_IN_CEILF:
3236 if (out_mode != SFmode || out_n != 4
3237 || in_mode != SFmode || in_n != 4)
3239 if (VECTOR_UNIT_VSX_P (V4SFmode))
3240 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3241 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3242 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3244 case BUILT_IN_FLOOR:
3245 if (VECTOR_UNIT_VSX_P (V2DFmode)
3246 && out_mode == DFmode && out_n == 2
3247 && in_mode == DFmode && in_n == 2)
3248 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3250 case BUILT_IN_FLOORF:
3251 if (out_mode != SFmode || out_n != 4
3252 || in_mode != SFmode || in_n != 4)
3254 if (VECTOR_UNIT_VSX_P (V4SFmode))
3255 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3256 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3257 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3259 case BUILT_IN_TRUNC:
3260 if (VECTOR_UNIT_VSX_P (V2DFmode)
3261 && out_mode == DFmode && out_n == 2
3262 && in_mode == DFmode && in_n == 2)
3263 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3265 case BUILT_IN_TRUNCF:
3266 if (out_mode != SFmode || out_n != 4
3267 || in_mode != SFmode || in_n != 4)
3269 if (VECTOR_UNIT_VSX_P (V4SFmode))
3270 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3271 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3272 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3274 case BUILT_IN_NEARBYINT:
3275 if (VECTOR_UNIT_VSX_P (V2DFmode)
3276 && flag_unsafe_math_optimizations
3277 && out_mode == DFmode && out_n == 2
3278 && in_mode == DFmode && in_n == 2)
3279 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3281 case BUILT_IN_NEARBYINTF:
3282 if (VECTOR_UNIT_VSX_P (V4SFmode)
3283 && flag_unsafe_math_optimizations
3284 && out_mode == SFmode && out_n == 4
3285 && in_mode == SFmode && in_n == 4)
3286 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3289 if (VECTOR_UNIT_VSX_P (V2DFmode)
3290 && !flag_trapping_math
3291 && out_mode == DFmode && out_n == 2
3292 && in_mode == DFmode && in_n == 2)
3293 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3295 case BUILT_IN_RINTF:
3296 if (VECTOR_UNIT_VSX_P (V4SFmode)
3297 && !flag_trapping_math
3298 && out_mode == SFmode && out_n == 4
3299 && in_mode == SFmode && in_n == 4)
3300 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3309 /* Implement TARGET_HANDLE_OPTION. */
3312 rs6000_handle_option (size_t code, const char *arg, int value)
3314 enum fpu_type_t fpu_type = FPU_NONE;
3320 target_flags &= ~(MASK_POWER | MASK_POWER2
3321 | MASK_MULTIPLE | MASK_STRING);
3322 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3323 | MASK_MULTIPLE | MASK_STRING);
3325 case OPT_mno_powerpc:
3326 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3327 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3328 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3329 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3332 target_flags &= ~MASK_MINIMAL_TOC;
3333 TARGET_NO_FP_IN_TOC = 0;
3334 TARGET_NO_SUM_IN_TOC = 0;
3335 target_flags_explicit |= MASK_MINIMAL_TOC;
3336 #ifdef TARGET_USES_SYSV4_OPT
3337 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3338 just the same as -mminimal-toc. */
3339 target_flags |= MASK_MINIMAL_TOC;
3340 target_flags_explicit |= MASK_MINIMAL_TOC;
3344 #ifdef TARGET_USES_SYSV4_OPT
3346 /* Make -mtoc behave like -mminimal-toc. */
3347 target_flags |= MASK_MINIMAL_TOC;
3348 target_flags_explicit |= MASK_MINIMAL_TOC;
3352 #ifdef TARGET_USES_AIX64_OPT
3357 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3358 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3359 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3362 #ifdef TARGET_USES_AIX64_OPT
3367 target_flags &= ~MASK_POWERPC64;
3368 target_flags_explicit |= MASK_POWERPC64;
3371 case OPT_minsert_sched_nops_:
3372 rs6000_sched_insert_nops_str = arg;
3375 case OPT_mminimal_toc:
3378 TARGET_NO_FP_IN_TOC = 0;
3379 TARGET_NO_SUM_IN_TOC = 0;
3386 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3387 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3394 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3395 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3399 case OPT_mpowerpc_gpopt:
3400 case OPT_mpowerpc_gfxopt:
3403 target_flags |= MASK_POWERPC;
3404 target_flags_explicit |= MASK_POWERPC;
3408 case OPT_maix_struct_return:
3409 case OPT_msvr4_struct_return:
3410 rs6000_explicit_options.aix_struct_ret = true;
3414 rs6000_explicit_options.vrsave = true;
3415 TARGET_ALTIVEC_VRSAVE = value;
3419 rs6000_explicit_options.vrsave = true;
3420 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3424 target_flags_explicit |= MASK_ISEL;
3426 rs6000_parse_yes_no_option ("isel", arg, &isel);
3428 target_flags |= MASK_ISEL;
3430 target_flags &= ~MASK_ISEL;
3434 rs6000_explicit_options.spe = true;
3439 rs6000_explicit_options.spe = true;
3440 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3444 rs6000_debug_name = arg;
3447 #ifdef TARGET_USES_SYSV4_OPT
3449 rs6000_abi_name = arg;
3453 rs6000_sdata_name = arg;
3456 case OPT_mtls_size_:
3457 rs6000_tls_size_string = arg;
3460 case OPT_mrelocatable:
3463 target_flags |= MASK_MINIMAL_TOC;
3464 target_flags_explicit |= MASK_MINIMAL_TOC;
3465 TARGET_NO_FP_IN_TOC = 1;
3469 case OPT_mrelocatable_lib:
3472 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3473 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3474 TARGET_NO_FP_IN_TOC = 1;
3478 target_flags &= ~MASK_RELOCATABLE;
3479 target_flags_explicit |= MASK_RELOCATABLE;
3485 if (!strcmp (arg, "altivec"))
3487 rs6000_explicit_options.altivec_abi = true;
3488 rs6000_altivec_abi = 1;
3490 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3493 else if (! strcmp (arg, "no-altivec"))
3495 rs6000_explicit_options.altivec_abi = true;
3496 rs6000_altivec_abi = 0;
3498 else if (! strcmp (arg, "spe"))
3500 rs6000_explicit_options.spe_abi = true;
3502 rs6000_altivec_abi = 0;
3503 if (!TARGET_SPE_ABI)
3504 error ("not configured for ABI: '%s'", arg);
3506 else if (! strcmp (arg, "no-spe"))
3508 rs6000_explicit_options.spe_abi = true;
3512 /* These are here for testing during development only, do not
3513 document in the manual please. */
3514 else if (! strcmp (arg, "d64"))
3516 rs6000_darwin64_abi = 1;
3517 warning (0, "Using darwin64 ABI");
3519 else if (! strcmp (arg, "d32"))
3521 rs6000_darwin64_abi = 0;
3522 warning (0, "Using old darwin ABI");
3525 else if (! strcmp (arg, "ibmlongdouble"))
3527 rs6000_explicit_options.ieee = true;
3528 rs6000_ieeequad = 0;
3529 warning (0, "Using IBM extended precision long double");
3531 else if (! strcmp (arg, "ieeelongdouble"))
3533 rs6000_explicit_options.ieee = true;
3534 rs6000_ieeequad = 1;
3535 warning (0, "Using IEEE extended precision long double");
3540 error ("unknown ABI specified: '%s'", arg);
3546 rs6000_select[1].string = arg;
3550 rs6000_select[2].string = arg;
3553 case OPT_mtraceback_:
3554 rs6000_traceback_name = arg;
3557 case OPT_mfloat_gprs_:
3558 rs6000_explicit_options.float_gprs = true;
3559 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3560 rs6000_float_gprs = 1;
3561 else if (! strcmp (arg, "double"))
3562 rs6000_float_gprs = 2;
3563 else if (! strcmp (arg, "no"))
3564 rs6000_float_gprs = 0;
3567 error ("invalid option for -mfloat-gprs: '%s'", arg);
3572 case OPT_mlong_double_:
3573 rs6000_explicit_options.long_double = true;
3574 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3575 if (value != 64 && value != 128)
3577 error ("Unknown switch -mlong-double-%s", arg);
3578 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3582 rs6000_long_double_type_size = value;
3585 case OPT_msched_costly_dep_:
3586 rs6000_sched_costly_dep_str = arg;
3590 rs6000_explicit_options.alignment = true;
3591 if (! strcmp (arg, "power"))
3593 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3594 some C library functions, so warn about it. The flag may be
3595 useful for performance studies from time to time though, so
3596 don't disable it entirely. */
3597 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3598 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3599 " it is incompatible with the installed C and C++ libraries");
3600 rs6000_alignment_flags = MASK_ALIGN_POWER;
3602 else if (! strcmp (arg, "natural"))
3603 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3606 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3611 case OPT_msingle_float:
3612 if (!TARGET_SINGLE_FPU)
3613 warning (0, "-msingle-float option equivalent to -mhard-float");
3614 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3615 rs6000_double_float = 0;
3616 target_flags &= ~MASK_SOFT_FLOAT;
3617 target_flags_explicit |= MASK_SOFT_FLOAT;
3620 case OPT_mdouble_float:
3621 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3622 rs6000_single_float = 1;
3623 target_flags &= ~MASK_SOFT_FLOAT;
3624 target_flags_explicit |= MASK_SOFT_FLOAT;
3627 case OPT_msimple_fpu:
3628 if (!TARGET_SINGLE_FPU)
3629 warning (0, "-msimple-fpu option ignored");
3632 case OPT_mhard_float:
3633 /* -mhard_float implies -msingle-float and -mdouble-float. */
3634 rs6000_single_float = rs6000_double_float = 1;
3637 case OPT_msoft_float:
3638 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3639 rs6000_single_float = rs6000_double_float = 0;
3643 fpu_type = rs6000_parse_fpu_option(arg);
3644 if (fpu_type != FPU_NONE)
3645 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3647 target_flags &= ~MASK_SOFT_FLOAT;
3648 target_flags_explicit |= MASK_SOFT_FLOAT;
3649 rs6000_xilinx_fpu = 1;
3650 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3651 rs6000_single_float = 1;
3652 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3653 rs6000_single_float = rs6000_double_float = 1;
3654 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3655 rs6000_simple_fpu = 1;
3659 /* -mfpu=none is equivalent to -msoft-float */
3660 target_flags |= MASK_SOFT_FLOAT;
3661 target_flags_explicit |= MASK_SOFT_FLOAT;
3662 rs6000_single_float = rs6000_double_float = 0;
3669 /* Do anything needed at the start of the asm file. */
3672 rs6000_file_start (void)
3676 const char *start = buffer;
3677 struct rs6000_cpu_select *ptr;
3678 const char *default_cpu = TARGET_CPU_DEFAULT;
3679 FILE *file = asm_out_file;
3681 default_file_start ();
3683 #ifdef TARGET_BI_ARCH
3684 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3688 if (flag_verbose_asm)
3690 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3691 rs6000_select[0].string = default_cpu;
3693 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3695 ptr = &rs6000_select[i];
3696 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3698 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3703 if (PPC405_ERRATUM77)
3705 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3709 #ifdef USING_ELFOS_H
3710 switch (rs6000_sdata)
3712 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3713 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3714 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3715 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3718 if (rs6000_sdata && g_switch_value)
3720 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3730 #ifdef HAVE_AS_GNU_ATTRIBUTE
3731 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3733 fprintf (file, "\t.gnu_attribute 4, %d\n",
3734 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3735 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3737 fprintf (file, "\t.gnu_attribute 8, %d\n",
3738 (TARGET_ALTIVEC_ABI ? 2
3739 : TARGET_SPE_ABI ? 3
3741 fprintf (file, "\t.gnu_attribute 12, %d\n",
3742 aix_struct_return ? 2 : 1);
3747 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3749 switch_to_section (toc_section);
3750 switch_to_section (text_section);
3755 /* Return nonzero if this function is known to have a null epilogue. */
3758 direct_return (void)
3760 if (reload_completed)
3762 rs6000_stack_t *info = rs6000_stack_info ();
3764 if (info->first_gp_reg_save == 32
3765 && info->first_fp_reg_save == 64
3766 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3767 && ! info->lr_save_p
3768 && ! info->cr_save_p
3769 && info->vrsave_mask == 0
3777 /* Return the number of instructions it takes to form a constant in an
3778 integer register. */
3781 num_insns_constant_wide (HOST_WIDE_INT value)
3783 /* signed constant loadable with {cal|addi} */
3784 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3787 /* constant loadable with {cau|addis} */
3788 else if ((value & 0xffff) == 0
3789 && (value >> 31 == -1 || value >> 31 == 0))
3792 #if HOST_BITS_PER_WIDE_INT == 64
3793 else if (TARGET_POWERPC64)
3795 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3796 HOST_WIDE_INT high = value >> 31;
3798 if (high == 0 || high == -1)
3804 return num_insns_constant_wide (high) + 1;
3806 return num_insns_constant_wide (low) + 1;
3808 return (num_insns_constant_wide (high)
3809 + num_insns_constant_wide (low) + 1);
3818 num_insns_constant (rtx op, enum machine_mode mode)
3820 HOST_WIDE_INT low, high;
3822 switch (GET_CODE (op))
3825 #if HOST_BITS_PER_WIDE_INT == 64
3826 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3827 && mask64_operand (op, mode))
3831 return num_insns_constant_wide (INTVAL (op));
3834 if (mode == SFmode || mode == SDmode)
3839 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3840 if (DECIMAL_FLOAT_MODE_P (mode))
3841 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3843 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3844 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3847 if (mode == VOIDmode || mode == DImode)
3849 high = CONST_DOUBLE_HIGH (op);
3850 low = CONST_DOUBLE_LOW (op);
3857 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3858 if (DECIMAL_FLOAT_MODE_P (mode))
3859 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3861 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3862 high = l[WORDS_BIG_ENDIAN == 0];
3863 low = l[WORDS_BIG_ENDIAN != 0];
3867 return (num_insns_constant_wide (low)
3868 + num_insns_constant_wide (high));
3871 if ((high == 0 && low >= 0)
3872 || (high == -1 && low < 0))
3873 return num_insns_constant_wide (low);
3875 else if (mask64_operand (op, mode))
3879 return num_insns_constant_wide (high) + 1;
3882 return (num_insns_constant_wide (high)
3883 + num_insns_constant_wide (low) + 1);
3891 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3892 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3893 corresponding element of the vector, but for V4SFmode and V2SFmode,
3894 the corresponding "float" is interpreted as an SImode integer. */
3897 const_vector_elt_as_int (rtx op, unsigned int elt)
3899 rtx tmp = CONST_VECTOR_ELT (op, elt);
3900 if (GET_MODE (op) == V4SFmode
3901 || GET_MODE (op) == V2SFmode)
3902 tmp = gen_lowpart (SImode, tmp);
3903 return INTVAL (tmp);
3906 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3907 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3908 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3909 all items are set to the same value and contain COPIES replicas of the
3910 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3911 operand and the others are set to the value of the operand's msb. */
3914 vspltis_constant (rtx op, unsigned step, unsigned copies)
3916 enum machine_mode mode = GET_MODE (op);
3917 enum machine_mode inner = GET_MODE_INNER (mode);
3920 unsigned nunits = GET_MODE_NUNITS (mode);
3921 unsigned bitsize = GET_MODE_BITSIZE (inner);
3922 unsigned mask = GET_MODE_MASK (inner);
3924 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3925 HOST_WIDE_INT splat_val = val;
3926 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3928 /* Construct the value to be splatted, if possible. If not, return 0. */
3929 for (i = 2; i <= copies; i *= 2)
3931 HOST_WIDE_INT small_val;
3933 small_val = splat_val >> bitsize;
3935 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3937 splat_val = small_val;
3940 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3941 if (EASY_VECTOR_15 (splat_val))
3944 /* Also check if we can splat, and then add the result to itself. Do so if
3945 the value is positive, of if the splat instruction is using OP's mode;
3946 for splat_val < 0, the splat and the add should use the same mode. */
3947 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3948 && (splat_val >= 0 || (step == 1 && copies == 1)))
3951 /* Also check if are loading up the most significant bit which can be done by
3952 loading up -1 and shifting the value left by -1. */
3953 else if (EASY_VECTOR_MSB (splat_val, inner))
3959 /* Check if VAL is present in every STEP-th element, and the
3960 other elements are filled with its most significant bit. */
3961 for (i = 0; i < nunits - 1; ++i)
3963 HOST_WIDE_INT desired_val;
3964 if (((i + 1) & (step - 1)) == 0)
3967 desired_val = msb_val;
3969 if (desired_val != const_vector_elt_as_int (op, i))
3977 /* Return true if OP is of the given MODE and can be synthesized
3978 with a vspltisb, vspltish or vspltisw. */
3981 easy_altivec_constant (rtx op, enum machine_mode mode)
3983 unsigned step, copies;
3985 if (mode == VOIDmode)
3986 mode = GET_MODE (op);
3987 else if (mode != GET_MODE (op))
3990 /* Start with a vspltisw. */
3991 step = GET_MODE_NUNITS (mode) / 4;
3994 if (vspltis_constant (op, step, copies))
3997 /* Then try with a vspltish. */
4003 if (vspltis_constant (op, step, copies))
4006 /* And finally a vspltisb. */
4012 if (vspltis_constant (op, step, copies))
4018 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4019 result is OP. Abort if it is not possible. */
4022 gen_easy_altivec_constant (rtx op)
4024 enum machine_mode mode = GET_MODE (op);
4025 int nunits = GET_MODE_NUNITS (mode);
4026 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4027 unsigned step = nunits / 4;
4028 unsigned copies = 1;
4030 /* Start with a vspltisw. */
4031 if (vspltis_constant (op, step, copies))
4032 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4034 /* Then try with a vspltish. */
4040 if (vspltis_constant (op, step, copies))
4041 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4043 /* And finally a vspltisb. */
4049 if (vspltis_constant (op, step, copies))
4050 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4056 output_vec_const_move (rtx *operands)
4059 enum machine_mode mode;
4064 mode = GET_MODE (dest);
4066 if (TARGET_VSX && zero_constant (vec, mode))
4067 return "xxlxor %x0,%x0,%x0";
4072 if (zero_constant (vec, mode))
4073 return "vxor %0,%0,%0";
4075 splat_vec = gen_easy_altivec_constant (vec);
4076 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4077 operands[1] = XEXP (splat_vec, 0);
4078 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4081 switch (GET_MODE (splat_vec))
4084 return "vspltisw %0,%1";
4087 return "vspltish %0,%1";
4090 return "vspltisb %0,%1";
4097 gcc_assert (TARGET_SPE);
4099 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4100 pattern of V1DI, V4HI, and V2SF.
4102 FIXME: We should probably return # and add post reload
4103 splitters for these, but this way is so easy ;-). */
4104 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4105 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4106 operands[1] = CONST_VECTOR_ELT (vec, 0);
4107 operands[2] = CONST_VECTOR_ELT (vec, 1);
4109 return "li %0,%1\n\tevmergelo %0,%0,%0";
4111 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4114 /* Initialize TARGET of vector PAIRED to VALS. */
4117 paired_expand_vector_init (rtx target, rtx vals)
4119 enum machine_mode mode = GET_MODE (target);
4120 int n_elts = GET_MODE_NUNITS (mode);
4122 rtx x, new_rtx, tmp, constant_op, op1, op2;
4125 for (i = 0; i < n_elts; ++i)
4127 x = XVECEXP (vals, 0, i);
4128 if (!CONSTANT_P (x))
4133 /* Load from constant pool. */
4134 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4140 /* The vector is initialized only with non-constants. */
4141 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4142 XVECEXP (vals, 0, 1));
4144 emit_move_insn (target, new_rtx);
4148 /* One field is non-constant and the other one is a constant. Load the
4149 constant from the constant pool and use ps_merge instruction to
4150 construct the whole vector. */
4151 op1 = XVECEXP (vals, 0, 0);
4152 op2 = XVECEXP (vals, 0, 1);
4154 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4156 tmp = gen_reg_rtx (GET_MODE (constant_op));
4157 emit_move_insn (tmp, constant_op);
4159 if (CONSTANT_P (op1))
4160 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4162 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4164 emit_move_insn (target, new_rtx);
4168 paired_expand_vector_move (rtx operands[])
4170 rtx op0 = operands[0], op1 = operands[1];
4172 emit_move_insn (op0, op1);
4175 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4176 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4177 operands for the relation operation COND. This is a recursive
4181 paired_emit_vector_compare (enum rtx_code rcode,
4182 rtx dest, rtx op0, rtx op1,
4183 rtx cc_op0, rtx cc_op1)
4185 rtx tmp = gen_reg_rtx (V2SFmode);
4188 gcc_assert (TARGET_PAIRED_FLOAT);
4189 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4195 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4199 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4200 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4204 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4207 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4210 tmp1 = gen_reg_rtx (V2SFmode);
4211 max = gen_reg_rtx (V2SFmode);
4212 min = gen_reg_rtx (V2SFmode);
4213 gen_reg_rtx (V2SFmode);
4215 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4216 emit_insn (gen_selv2sf4
4217 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4218 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4219 emit_insn (gen_selv2sf4
4220 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4221 emit_insn (gen_subv2sf3 (tmp1, min, max));
4222 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4225 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4228 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4231 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4234 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4237 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4246 /* Emit vector conditional expression.
4247 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4248 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4251 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4252 rtx cond, rtx cc_op0, rtx cc_op1)
4254 enum rtx_code rcode = GET_CODE (cond);
4256 if (!TARGET_PAIRED_FLOAT)
4259 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4264 /* Initialize vector TARGET to VALS. */
4267 rs6000_expand_vector_init (rtx target, rtx vals)
4269 enum machine_mode mode = GET_MODE (target);
4270 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4271 int n_elts = GET_MODE_NUNITS (mode);
4272 int n_var = 0, one_var = -1;
4273 bool all_same = true, all_const_zero = true;
4277 for (i = 0; i < n_elts; ++i)
4279 x = XVECEXP (vals, 0, i);
4280 if (!CONSTANT_P (x))
4281 ++n_var, one_var = i;
4282 else if (x != CONST0_RTX (inner_mode))
4283 all_const_zero = false;
4285 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4291 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4292 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4293 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4295 /* Zero register. */
4296 emit_insn (gen_rtx_SET (VOIDmode, target,
4297 gen_rtx_XOR (mode, target, target)));
4300 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4302 /* Splat immediate. */
4303 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4308 /* Load from constant pool. */
4309 emit_move_insn (target, const_vec);
4314 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4315 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4319 rtx element = XVECEXP (vals, 0, 0);
4320 if (mode == V2DFmode)
4321 emit_insn (gen_vsx_splat_v2df (target, element));
4323 emit_insn (gen_vsx_splat_v2di (target, element));
4327 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4328 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4329 if (mode == V2DFmode)
4330 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4332 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4337 /* With single precision floating point on VSX, know that internally single
4338 precision is actually represented as a double, and either make 2 V2DF
4339 vectors, and convert these vectors to single precision, or do one
4340 conversion, and splat the result to the other elements. */
4341 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4345 rtx freg = gen_reg_rtx (V4SFmode);
4346 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4348 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4349 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4353 rtx dbl_even = gen_reg_rtx (V2DFmode);
4354 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4355 rtx flt_even = gen_reg_rtx (V4SFmode);
4356 rtx flt_odd = gen_reg_rtx (V4SFmode);
4358 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4359 copy_to_reg (XVECEXP (vals, 0, 0)),
4360 copy_to_reg (XVECEXP (vals, 0, 1))));
4361 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4362 copy_to_reg (XVECEXP (vals, 0, 2)),
4363 copy_to_reg (XVECEXP (vals, 0, 3))));
4364 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4365 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4366 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4371 /* Store value to stack temp. Load vector element. Splat. However, splat
4372 of 64-bit items is not supported on Altivec. */
4373 if (all_same && GET_MODE_SIZE (mode) <= 4)
4375 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4376 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4377 XVECEXP (vals, 0, 0));
4378 x = gen_rtx_UNSPEC (VOIDmode,
4379 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4380 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4382 gen_rtx_SET (VOIDmode,
4385 x = gen_rtx_VEC_SELECT (inner_mode, target,
4386 gen_rtx_PARALLEL (VOIDmode,
4387 gen_rtvec (1, const0_rtx)));
4388 emit_insn (gen_rtx_SET (VOIDmode, target,
4389 gen_rtx_VEC_DUPLICATE (mode, x)));
4393 /* One field is non-constant. Load constant then overwrite
4397 rtx copy = copy_rtx (vals);
4399 /* Load constant part of vector, substitute neighboring value for
4401 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4402 rs6000_expand_vector_init (target, copy);
4404 /* Insert variable. */
4405 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4409 /* Construct the vector in memory one field at a time
4410 and load the whole vector. */
4411 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4412 for (i = 0; i < n_elts; i++)
4413 emit_move_insn (adjust_address_nv (mem, inner_mode,
4414 i * GET_MODE_SIZE (inner_mode)),
4415 XVECEXP (vals, 0, i));
4416 emit_move_insn (target, mem);
4419 /* Set field ELT of TARGET to VAL. */
4422 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4424 enum machine_mode mode = GET_MODE (target);
4425 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4426 rtx reg = gen_reg_rtx (mode);
4428 int width = GET_MODE_SIZE (inner_mode);
4431 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4433 rtx (*set_func) (rtx, rtx, rtx, rtx)
4434 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4435 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4439 /* Load single variable value. */
4440 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4441 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4442 x = gen_rtx_UNSPEC (VOIDmode,
4443 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4444 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4446 gen_rtx_SET (VOIDmode,
4450 /* Linear sequence. */
4451 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4452 for (i = 0; i < 16; ++i)
4453 XVECEXP (mask, 0, i) = GEN_INT (i);
4455 /* Set permute mask to insert element into target. */
4456 for (i = 0; i < width; ++i)
4457 XVECEXP (mask, 0, elt*width + i)
4458 = GEN_INT (i + 0x10);
4459 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4460 x = gen_rtx_UNSPEC (mode,
4461 gen_rtvec (3, target, reg,
4462 force_reg (V16QImode, x)),
4464 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4467 /* Extract field ELT from VEC into TARGET. */
4470 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4472 enum machine_mode mode = GET_MODE (vec);
4473 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4476 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4478 rtx (*extract_func) (rtx, rtx, rtx)
4479 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4480 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4484 /* Allocate mode-sized buffer. */
4485 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4487 /* Add offset to field within buffer matching vector element. */
4488 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4490 /* Store single field into mode-sized buffer. */
4491 x = gen_rtx_UNSPEC (VOIDmode,
4492 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4493 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4495 gen_rtx_SET (VOIDmode,
4498 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4501 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4502 implement ANDing by the mask IN. */
4504 build_mask64_2_operands (rtx in, rtx *out)
4506 #if HOST_BITS_PER_WIDE_INT >= 64
4507 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4510 gcc_assert (GET_CODE (in) == CONST_INT);
4515 /* Assume c initially something like 0x00fff000000fffff. The idea
4516 is to rotate the word so that the middle ^^^^^^ group of zeros
4517 is at the MS end and can be cleared with an rldicl mask. We then
4518 rotate back and clear off the MS ^^ group of zeros with a
4520 c = ~c; /* c == 0xff000ffffff00000 */
4521 lsb = c & -c; /* lsb == 0x0000000000100000 */
4522 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4523 c = ~c; /* c == 0x00fff000000fffff */
4524 c &= -lsb; /* c == 0x00fff00000000000 */
4525 lsb = c & -c; /* lsb == 0x0000100000000000 */
4526 c = ~c; /* c == 0xff000fffffffffff */
4527 c &= -lsb; /* c == 0xff00000000000000 */
4529 while ((lsb >>= 1) != 0)
4530 shift++; /* shift == 44 on exit from loop */
4531 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4532 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4533 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4537 /* Assume c initially something like 0xff000f0000000000. The idea
4538 is to rotate the word so that the ^^^ middle group of zeros
4539 is at the LS end and can be cleared with an rldicr mask. We then
4540 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4542 lsb = c & -c; /* lsb == 0x0000010000000000 */
4543 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4544 c = ~c; /* c == 0x00fff0ffffffffff */
4545 c &= -lsb; /* c == 0x00fff00000000000 */
4546 lsb = c & -c; /* lsb == 0x0000100000000000 */
4547 c = ~c; /* c == 0xff000fffffffffff */
4548 c &= -lsb; /* c == 0xff00000000000000 */
4550 while ((lsb >>= 1) != 0)
4551 shift++; /* shift == 44 on exit from loop */
4552 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4553 m1 >>= shift; /* m1 == 0x0000000000000fff */
4554 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4557 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4558 masks will be all 1's. We are guaranteed more than one transition. */
4559 out[0] = GEN_INT (64 - shift);
4560 out[1] = GEN_INT (m1);
4561 out[2] = GEN_INT (shift);
4562 out[3] = GEN_INT (m2);
4570 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4573 invalid_e500_subreg (rtx op, enum machine_mode mode)
4575 if (TARGET_E500_DOUBLE)
4577 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4578 subreg:TI and reg:TF. Decimal float modes are like integer
4579 modes (only low part of each register used) for this
4581 if (GET_CODE (op) == SUBREG
4582 && (mode == SImode || mode == DImode || mode == TImode
4583 || mode == DDmode || mode == TDmode)
4584 && REG_P (SUBREG_REG (op))
4585 && (GET_MODE (SUBREG_REG (op)) == DFmode
4586 || GET_MODE (SUBREG_REG (op)) == TFmode))
4589 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4591 if (GET_CODE (op) == SUBREG
4592 && (mode == DFmode || mode == TFmode)
4593 && REG_P (SUBREG_REG (op))
4594 && (GET_MODE (SUBREG_REG (op)) == DImode
4595 || GET_MODE (SUBREG_REG (op)) == TImode
4596 || GET_MODE (SUBREG_REG (op)) == DDmode
4597 || GET_MODE (SUBREG_REG (op)) == TDmode))
4602 && GET_CODE (op) == SUBREG
4604 && REG_P (SUBREG_REG (op))
4605 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4611 /* AIX increases natural record alignment to doubleword if the first
4612 field is an FP double while the FP fields remain word aligned. */
4615 rs6000_special_round_type_align (tree type, unsigned int computed,
4616 unsigned int specified)
4618 unsigned int align = MAX (computed, specified);
4619 tree field = TYPE_FIELDS (type);
4621 /* Skip all non field decls */
4622 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4623 field = TREE_CHAIN (field);
4625 if (field != NULL && field != type)
4627 type = TREE_TYPE (field);
4628 while (TREE_CODE (type) == ARRAY_TYPE)
4629 type = TREE_TYPE (type);
4631 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4632 align = MAX (align, 64);
4638 /* Darwin increases record alignment to the natural alignment of
4642 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4643 unsigned int specified)
4645 unsigned int align = MAX (computed, specified);
4647 if (TYPE_PACKED (type))
4650 /* Find the first field, looking down into aggregates. */
4652 tree field = TYPE_FIELDS (type);
4653 /* Skip all non field decls */
4654 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4655 field = TREE_CHAIN (field);
4658 /* A packed field does not contribute any extra alignment. */
4659 if (DECL_PACKED (field))
4661 type = TREE_TYPE (field);
4662 while (TREE_CODE (type) == ARRAY_TYPE)
4663 type = TREE_TYPE (type);
4664 } while (AGGREGATE_TYPE_P (type));
4666 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4667 align = MAX (align, TYPE_ALIGN (type));
4672 /* Return 1 for an operand in small memory on V.4/eabi. */
4675 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4676 enum machine_mode mode ATTRIBUTE_UNUSED)
4681 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4684 if (DEFAULT_ABI != ABI_V4)
4687 /* Vector and float memory instructions have a limited offset on the
4688 SPE, so using a vector or float variable directly as an operand is
4691 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4694 if (GET_CODE (op) == SYMBOL_REF)
4697 else if (GET_CODE (op) != CONST
4698 || GET_CODE (XEXP (op, 0)) != PLUS
4699 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4700 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4705 rtx sum = XEXP (op, 0);
4706 HOST_WIDE_INT summand;
4708 /* We have to be careful here, because it is the referenced address
4709 that must be 32k from _SDA_BASE_, not just the symbol. */
4710 summand = INTVAL (XEXP (sum, 1));
4711 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4714 sym_ref = XEXP (sum, 0);
4717 return SYMBOL_REF_SMALL_P (sym_ref);
4723 /* Return true if either operand is a general purpose register. */
4726 gpr_or_gpr_p (rtx op0, rtx op1)
4728 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4729 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4733 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4736 reg_offset_addressing_ok_p (enum machine_mode mode)
4746 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4747 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4755 /* Paired vector modes. Only reg+reg addressing is valid. */
4756 if (TARGET_PAIRED_FLOAT)
4768 virtual_stack_registers_memory_p (rtx op)
4772 if (GET_CODE (op) == REG)
4773 regnum = REGNO (op);
4775 else if (GET_CODE (op) == PLUS
4776 && GET_CODE (XEXP (op, 0)) == REG
4777 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4778 regnum = REGNO (XEXP (op, 0));
4783 return (regnum >= FIRST_VIRTUAL_REGISTER
4784 && regnum <= LAST_VIRTUAL_REGISTER);
4788 constant_pool_expr_p (rtx op)
4792 split_const (op, &base, &offset);
4793 return (GET_CODE (base) == SYMBOL_REF
4794 && CONSTANT_POOL_ADDRESS_P (base)
4795 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4799 toc_relative_expr_p (rtx op)
4803 if (GET_CODE (op) != CONST)
4806 split_const (op, &base, &offset);
4807 return (GET_CODE (base) == UNSPEC
4808 && XINT (base, 1) == UNSPEC_TOCREL);
4812 legitimate_constant_pool_address_p (rtx x)
4815 && GET_CODE (x) == PLUS
4816 && GET_CODE (XEXP (x, 0)) == REG
4817 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4818 && toc_relative_expr_p (XEXP (x, 1)));
4822 legitimate_small_data_p (enum machine_mode mode, rtx x)
4824 return (DEFAULT_ABI == ABI_V4
4825 && !flag_pic && !TARGET_TOC
4826 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4827 && small_data_operand (x, mode));
4830 /* SPE offset addressing is limited to 5-bits worth of double words. */
4831 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4834 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4836 unsigned HOST_WIDE_INT offset, extra;
4838 if (GET_CODE (x) != PLUS)
4840 if (GET_CODE (XEXP (x, 0)) != REG)
4842 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4844 if (!reg_offset_addressing_ok_p (mode))
4845 return virtual_stack_registers_memory_p (x);
4846 if (legitimate_constant_pool_address_p (x))
4848 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4851 offset = INTVAL (XEXP (x, 1));
4859 /* SPE vector modes. */
4860 return SPE_CONST_OFFSET_OK (offset);
4863 if (TARGET_E500_DOUBLE)
4864 return SPE_CONST_OFFSET_OK (offset);
4866 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4868 if (VECTOR_MEM_VSX_P (DFmode))
4873 /* On e500v2, we may have:
4875 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4877 Which gets addressed with evldd instructions. */
4878 if (TARGET_E500_DOUBLE)
4879 return SPE_CONST_OFFSET_OK (offset);
4881 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4883 else if (offset & 3)
4888 if (TARGET_E500_DOUBLE)
4889 return (SPE_CONST_OFFSET_OK (offset)
4890 && SPE_CONST_OFFSET_OK (offset + 8));
4894 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4896 else if (offset & 3)
4907 return (offset < 0x10000) && (offset + extra < 0x10000);
4911 legitimate_indexed_address_p (rtx x, int strict)
4915 if (GET_CODE (x) != PLUS)
4921 /* Recognize the rtl generated by reload which we know will later be
4922 replaced with proper base and index regs. */
4924 && reload_in_progress
4925 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4929 return (REG_P (op0) && REG_P (op1)
4930 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4931 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4932 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4933 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4937 avoiding_indexed_address_p (enum machine_mode mode)
4939 /* Avoid indexed addressing for modes that have non-indexed
4940 load/store instruction forms. */
4941 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4945 legitimate_indirect_address_p (rtx x, int strict)
4947 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4951 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4953 if (!TARGET_MACHO || !flag_pic
4954 || mode != SImode || GET_CODE (x) != MEM)
4958 if (GET_CODE (x) != LO_SUM)
4960 if (GET_CODE (XEXP (x, 0)) != REG)
4962 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4966 return CONSTANT_P (x);
4970 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4972 if (GET_CODE (x) != LO_SUM)
4974 if (GET_CODE (XEXP (x, 0)) != REG)
4976 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4978 /* Restrict addressing for DI because of our SUBREG hackery. */
4979 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4980 || mode == DDmode || mode == TDmode
4985 if (TARGET_ELF || TARGET_MACHO)
4987 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4991 if (GET_MODE_NUNITS (mode) != 1)
4993 if (GET_MODE_BITSIZE (mode) > 64
4994 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4995 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4996 && (mode == DFmode || mode == DDmode))))
4999 return CONSTANT_P (x);
5006 /* Try machine-dependent ways of modifying an illegitimate address
5007 to be legitimate. If we find one, return the new, valid address.
5008 This is used from only one place: `memory_address' in explow.c.
5010 OLDX is the address as it was before break_out_memory_refs was
5011 called. In some cases it is useful to look at this to decide what
5014 It is always safe for this function to do nothing. It exists to
5015 recognize opportunities to optimize the output.
5017 On RS/6000, first check for the sum of a register with a constant
5018 integer that is out of range. If so, generate code to add the
5019 constant with the low-order 16 bits masked to the register and force
5020 this result into another register (this can be done with `cau').
5021 Then generate an address of REG+(CONST&0xffff), allowing for the
5022 possibility of bit 16 being a one.
5024 Then check for the sum of a register and something not constant, try to
5025 load the other things into a register and return the sum. */
5028 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5029 enum machine_mode mode)
5031 unsigned int extra = 0;
5033 if (!reg_offset_addressing_ok_p (mode))
5035 if (virtual_stack_registers_memory_p (x))
5038 /* In theory we should not be seeing addresses of the form reg+0,
5039 but just in case it is generated, optimize it away. */
5040 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5041 return force_reg (Pmode, XEXP (x, 0));
5043 /* Make sure both operands are registers. */
5044 else if (GET_CODE (x) == PLUS)
5045 return gen_rtx_PLUS (Pmode,
5046 force_reg (Pmode, XEXP (x, 0)),
5047 force_reg (Pmode, XEXP (x, 1)));
5049 return force_reg (Pmode, x);
5051 if (GET_CODE (x) == SYMBOL_REF)
5053 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5055 return rs6000_legitimize_tls_address (x, model);
5065 if (!TARGET_POWERPC64)
5073 extra = TARGET_POWERPC64 ? 8 : 12;
5079 if (GET_CODE (x) == PLUS
5080 && GET_CODE (XEXP (x, 0)) == REG
5081 && GET_CODE (XEXP (x, 1)) == CONST_INT
5082 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5084 && !((TARGET_POWERPC64
5085 && (mode == DImode || mode == TImode)
5086 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5087 || SPE_VECTOR_MODE (mode)
5088 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5089 || mode == DImode || mode == DDmode
5090 || mode == TDmode))))
5092 HOST_WIDE_INT high_int, low_int;
5094 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5095 if (low_int >= 0x8000 - extra)
5097 high_int = INTVAL (XEXP (x, 1)) - low_int;
5098 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5099 GEN_INT (high_int)), 0);
5100 return plus_constant (sum, low_int);
5102 else if (GET_CODE (x) == PLUS
5103 && GET_CODE (XEXP (x, 0)) == REG
5104 && GET_CODE (XEXP (x, 1)) != CONST_INT
5105 && GET_MODE_NUNITS (mode) == 1
5106 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5108 || ((mode != DImode && mode != DFmode && mode != DDmode)
5109 || (TARGET_E500_DOUBLE && mode != DDmode)))
5110 && (TARGET_POWERPC64 || mode != DImode)
5111 && !avoiding_indexed_address_p (mode)
5116 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5117 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5119 else if (SPE_VECTOR_MODE (mode)
5120 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5121 || mode == DDmode || mode == TDmode
5122 || mode == DImode)))
5126 /* We accept [reg + reg] and [reg + OFFSET]. */
5128 if (GET_CODE (x) == PLUS)
5130 rtx op1 = XEXP (x, 0);
5131 rtx op2 = XEXP (x, 1);
5134 op1 = force_reg (Pmode, op1);
5136 if (GET_CODE (op2) != REG
5137 && (GET_CODE (op2) != CONST_INT
5138 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5139 || (GET_MODE_SIZE (mode) > 8
5140 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5141 op2 = force_reg (Pmode, op2);
5143 /* We can't always do [reg + reg] for these, because [reg +
5144 reg + offset] is not a legitimate addressing mode. */
5145 y = gen_rtx_PLUS (Pmode, op1, op2);
5147 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5148 return force_reg (Pmode, y);
5153 return force_reg (Pmode, x);
5159 && GET_CODE (x) != CONST_INT
5160 && GET_CODE (x) != CONST_DOUBLE
5162 && GET_MODE_NUNITS (mode) == 1
5163 && (GET_MODE_BITSIZE (mode) <= 32
5164 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5165 && (mode == DFmode || mode == DDmode))))
5167 rtx reg = gen_reg_rtx (Pmode);
5168 emit_insn (gen_elf_high (reg, x));
5169 return gen_rtx_LO_SUM (Pmode, reg, x);
5171 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5174 && ! MACHO_DYNAMIC_NO_PIC_P
5176 && GET_CODE (x) != CONST_INT
5177 && GET_CODE (x) != CONST_DOUBLE
5179 && GET_MODE_NUNITS (mode) == 1
5180 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5181 || (mode != DFmode && mode != DDmode))
5185 rtx reg = gen_reg_rtx (Pmode);
5186 emit_insn (gen_macho_high (reg, x));
5187 return gen_rtx_LO_SUM (Pmode, reg, x);
5190 && GET_CODE (x) == SYMBOL_REF
5191 && constant_pool_expr_p (x)
5192 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5194 return create_TOC_reference (x);
5200 /* Debug version of rs6000_legitimize_address. */
5202 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5208 ret = rs6000_legitimize_address (x, oldx, mode);
5209 insns = get_insns ();
5215 "\nrs6000_legitimize_address: mode %s, old code %s, "
5216 "new code %s, modified\n",
5217 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5218 GET_RTX_NAME (GET_CODE (ret)));
5220 fprintf (stderr, "Original address:\n");
5223 fprintf (stderr, "oldx:\n");
5226 fprintf (stderr, "New address:\n");
5231 fprintf (stderr, "Insns added:\n");
5232 debug_rtx_list (insns, 20);
5238 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5239 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5250 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5251 We need to emit DTP-relative relocations. */
5254 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5259 fputs ("\t.long\t", file);
5262 fputs (DOUBLE_INT_ASM_OP, file);
5267 output_addr_const (file, x);
5268 fputs ("@dtprel+0x8000", file);
5271 /* In the name of slightly smaller debug output, and to cater to
5272 general assembler lossage, recognize various UNSPEC sequences
5273 and turn them back into a direct symbol reference. */
5276 rs6000_delegitimize_address (rtx orig_x)
5280 orig_x = delegitimize_mem_from_attrs (orig_x);
5285 if (GET_CODE (x) == PLUS
5286 && GET_CODE (XEXP (x, 1)) == CONST
5287 && GET_CODE (XEXP (x, 0)) == REG
5288 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5290 y = XEXP (XEXP (x, 1), 0);
5291 if (GET_CODE (y) == UNSPEC
5292 && XINT (y, 1) == UNSPEC_TOCREL)
5294 y = XVECEXP (y, 0, 0);
5295 if (!MEM_P (orig_x))
5298 return replace_equiv_address_nv (orig_x, y);
5304 && GET_CODE (orig_x) == LO_SUM
5305 && GET_CODE (XEXP (x, 1)) == CONST)
5307 y = XEXP (XEXP (x, 1), 0);
5308 if (GET_CODE (y) == UNSPEC
5309 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5310 return XVECEXP (y, 0, 0);
5316 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5318 static GTY(()) rtx rs6000_tls_symbol;
5320 rs6000_tls_get_addr (void)
5322 if (!rs6000_tls_symbol)
5323 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5325 return rs6000_tls_symbol;
5328 /* Construct the SYMBOL_REF for TLS GOT references. */
5330 static GTY(()) rtx rs6000_got_symbol;
5332 rs6000_got_sym (void)
5334 if (!rs6000_got_symbol)
5336 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5337 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5338 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5341 return rs6000_got_symbol;
5344 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5345 this (thread-local) address. */
5348 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5352 dest = gen_reg_rtx (Pmode);
5353 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5359 tlsreg = gen_rtx_REG (Pmode, 13);
5360 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5364 tlsreg = gen_rtx_REG (Pmode, 2);
5365 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5369 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5373 tmp = gen_reg_rtx (Pmode);
5376 tlsreg = gen_rtx_REG (Pmode, 13);
5377 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5381 tlsreg = gen_rtx_REG (Pmode, 2);
5382 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5386 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5388 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5393 rtx r3, got, tga, tmp1, tmp2, eqv;
5395 /* We currently use relocations like @got@tlsgd for tls, which
5396 means the linker will handle allocation of tls entries, placing
5397 them in the .got section. So use a pointer to the .got section,
5398 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5399 or to secondary GOT sections used by 32-bit -fPIC. */
5401 got = gen_rtx_REG (Pmode, 2);
5405 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5408 rtx gsym = rs6000_got_sym ();
5409 got = gen_reg_rtx (Pmode);
5411 rs6000_emit_move (got, gsym, Pmode);
5417 tmp1 = gen_reg_rtx (Pmode);
5418 tmp2 = gen_reg_rtx (Pmode);
5419 tmp3 = gen_reg_rtx (Pmode);
5420 mem = gen_const_mem (Pmode, tmp1);
5422 emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5423 emit_move_insn (tmp1,
5424 gen_rtx_REG (Pmode, LR_REGNO));
5425 emit_move_insn (tmp2, mem);
5426 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5427 last = emit_move_insn (got, tmp3);
5428 set_unique_reg_note (last, REG_EQUAL, gsym);
5433 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5435 r3 = gen_rtx_REG (Pmode, 3);
5436 tga = rs6000_tls_get_addr ();
5438 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5439 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5440 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5441 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5442 else if (DEFAULT_ABI == ABI_V4)
5443 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5448 insn = emit_call_insn (insn);
5449 RTL_CONST_CALL_P (insn) = 1;
5450 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5451 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5452 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5453 insn = get_insns ();
5455 emit_libcall_block (insn, dest, r3, addr);
5457 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5459 r3 = gen_rtx_REG (Pmode, 3);
5460 tga = rs6000_tls_get_addr ();
5462 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5463 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5464 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5465 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5466 else if (DEFAULT_ABI == ABI_V4)
5467 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5472 insn = emit_call_insn (insn);
5473 RTL_CONST_CALL_P (insn) = 1;
5474 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5475 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5476 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5477 insn = get_insns ();
5479 tmp1 = gen_reg_rtx (Pmode);
5480 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5482 emit_libcall_block (insn, tmp1, r3, eqv);
5483 if (rs6000_tls_size == 16)
5486 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5488 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5490 else if (rs6000_tls_size == 32)
5492 tmp2 = gen_reg_rtx (Pmode);
5494 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5496 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5499 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5501 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5505 tmp2 = gen_reg_rtx (Pmode);
5507 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5509 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5511 insn = gen_rtx_SET (Pmode, dest,
5512 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5518 /* IE, or 64-bit offset LE. */
5519 tmp2 = gen_reg_rtx (Pmode);
5521 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5523 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5526 insn = gen_tls_tls_64 (dest, tmp2, addr);
5528 insn = gen_tls_tls_32 (dest, tmp2, addr);
5536 /* Return 1 if X contains a thread-local symbol. */
5539 rs6000_tls_referenced_p (rtx x)
5541 if (! TARGET_HAVE_TLS)
5544 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5547 /* Return 1 if *X is a thread-local symbol. This is the same as
5548 rs6000_tls_symbol_ref except for the type of the unused argument. */
5551 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5553 return RS6000_SYMBOL_REF_TLS_P (*x);
5556 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5557 replace the input X, or the original X if no replacement is called for.
5558 The output parameter *WIN is 1 if the calling macro should goto WIN,
5561 For RS/6000, we wish to handle large displacements off a base
5562 register by splitting the addend across an addiu/addis and the mem insn.
5563 This cuts number of extra insns needed from 3 to 1.
5565 On Darwin, we use this to generate code for floating point constants.
5566 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5567 The Darwin code is inside #if TARGET_MACHO because only then are the
5568 machopic_* functions defined. */
5570 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5571 int opnum, int type,
5572 int ind_levels ATTRIBUTE_UNUSED, int *win)
5574 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5576 /* We must recognize output that we have already generated ourselves. */
5577 if (GET_CODE (x) == PLUS
5578 && GET_CODE (XEXP (x, 0)) == PLUS
5579 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5580 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5581 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5583 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5584 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5585 opnum, (enum reload_type)type);
5591 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5592 && GET_CODE (x) == LO_SUM
5593 && GET_CODE (XEXP (x, 0)) == PLUS
5594 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5595 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5596 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5597 && machopic_operand_p (XEXP (x, 1)))
5599 /* Result of previous invocation of this function on Darwin
5600 floating point constant. */
5601 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5602 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5603 opnum, (enum reload_type)type);
5609 /* Force ld/std non-word aligned offset into base register by wrapping
5611 if (GET_CODE (x) == PLUS
5612 && GET_CODE (XEXP (x, 0)) == REG
5613 && REGNO (XEXP (x, 0)) < 32
5614 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5615 && GET_CODE (XEXP (x, 1)) == CONST_INT
5617 && (INTVAL (XEXP (x, 1)) & 3) != 0
5618 && VECTOR_MEM_NONE_P (mode)
5619 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5620 && TARGET_POWERPC64)
5622 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5623 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5624 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5625 opnum, (enum reload_type) type);
5630 if (GET_CODE (x) == PLUS
5631 && GET_CODE (XEXP (x, 0)) == REG
5632 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5633 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5634 && GET_CODE (XEXP (x, 1)) == CONST_INT
5636 && !SPE_VECTOR_MODE (mode)
5637 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5638 || mode == DDmode || mode == TDmode
5640 && VECTOR_MEM_NONE_P (mode))
5642 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5643 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5645 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5647 /* Check for 32-bit overflow. */
5648 if (high + low != val)
5654 /* Reload the high part into a base reg; leave the low part
5655 in the mem directly. */
5657 x = gen_rtx_PLUS (GET_MODE (x),
5658 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5662 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5663 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5664 opnum, (enum reload_type)type);
5669 if (GET_CODE (x) == SYMBOL_REF
5671 && VECTOR_MEM_NONE_P (mode)
5672 && !SPE_VECTOR_MODE (mode)
5674 && DEFAULT_ABI == ABI_DARWIN
5675 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5677 && DEFAULT_ABI == ABI_V4
5680 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5681 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5685 && (mode != DImode || TARGET_POWERPC64)
5686 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5687 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5692 rtx offset = machopic_gen_offset (x);
5693 x = gen_rtx_LO_SUM (GET_MODE (x),
5694 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5695 gen_rtx_HIGH (Pmode, offset)), offset);
5699 x = gen_rtx_LO_SUM (GET_MODE (x),
5700 gen_rtx_HIGH (Pmode, x), x);
5702 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5703 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5704 opnum, (enum reload_type)type);
5709 /* Reload an offset address wrapped by an AND that represents the
5710 masking of the lower bits. Strip the outer AND and let reload
5711 convert the offset address into an indirect address. For VSX,
5712 force reload to create the address with an AND in a separate
5713 register, because we can't guarantee an altivec register will
5715 if (VECTOR_MEM_ALTIVEC_P (mode)
5716 && GET_CODE (x) == AND
5717 && GET_CODE (XEXP (x, 0)) == PLUS
5718 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5719 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5720 && GET_CODE (XEXP (x, 1)) == CONST_INT
5721 && INTVAL (XEXP (x, 1)) == -16)
5730 && GET_CODE (x) == SYMBOL_REF
5731 && constant_pool_expr_p (x)
5732 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5734 x = create_TOC_reference (x);
5742 /* Debug version of rs6000_legitimize_reload_address. */
5744 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5745 int opnum, int type,
5746 int ind_levels, int *win)
5748 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5751 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5752 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5753 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5757 fprintf (stderr, "Same address returned\n");
5759 fprintf (stderr, "NULL returned\n");
5762 fprintf (stderr, "New address:\n");
5769 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5770 that is a valid memory address for an instruction.
5771 The MODE argument is the machine mode for the MEM expression
5772 that wants to use this address.
5774 On the RS/6000, there are four valid address: a SYMBOL_REF that
5775 refers to a constant pool entry of an address (or the sum of it
5776 plus a constant), a short (16-bit signed) constant plus a register,
5777 the sum of two registers, or a register indirect, possibly with an
5778 auto-increment. For DFmode, DDmode and DImode with a constant plus
5779 register, we must ensure that both words are addressable or PowerPC64
5780 with offset word aligned.
5782 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5783 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5784 because adjacent memory cells are accessed by adding word-sized offsets
5785 during assembly output. */
5787 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5789 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5791 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5792 if (VECTOR_MEM_ALTIVEC_P (mode)
5793 && GET_CODE (x) == AND
5794 && GET_CODE (XEXP (x, 1)) == CONST_INT
5795 && INTVAL (XEXP (x, 1)) == -16)
5798 if (RS6000_SYMBOL_REF_TLS_P (x))
5800 if (legitimate_indirect_address_p (x, reg_ok_strict))
5802 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5803 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5804 && !SPE_VECTOR_MODE (mode)
5807 /* Restrict addressing for DI because of our SUBREG hackery. */
5808 && !(TARGET_E500_DOUBLE
5809 && (mode == DFmode || mode == DDmode || mode == DImode))
5811 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5813 if (virtual_stack_registers_memory_p (x))
5815 if (reg_offset_p && legitimate_small_data_p (mode, x))
5817 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5819 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5822 && GET_CODE (x) == PLUS
5823 && GET_CODE (XEXP (x, 0)) == REG
5824 && (XEXP (x, 0) == virtual_stack_vars_rtx
5825 || XEXP (x, 0) == arg_pointer_rtx)
5826 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5828 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5833 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5835 || (mode != DFmode && mode != DDmode)
5836 || (TARGET_E500_DOUBLE && mode != DDmode))
5837 && (TARGET_POWERPC64 || mode != DImode)
5838 && !avoiding_indexed_address_p (mode)
5839 && legitimate_indexed_address_p (x, reg_ok_strict))
5841 if (GET_CODE (x) == PRE_MODIFY
5845 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5847 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5848 && (TARGET_POWERPC64 || mode != DImode)
5849 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5850 && !SPE_VECTOR_MODE (mode)
5851 /* Restrict addressing for DI because of our SUBREG hackery. */
5852 && !(TARGET_E500_DOUBLE
5853 && (mode == DFmode || mode == DDmode || mode == DImode))
5855 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5856 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5857 || (!avoiding_indexed_address_p (mode)
5858 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5859 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5861 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5866 /* Debug version of rs6000_legitimate_address_p. */
5868 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5871 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5873 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5874 "strict = %d, code = %s\n",
5875 ret ? "true" : "false",
5876 GET_MODE_NAME (mode),
5878 GET_RTX_NAME (GET_CODE (x)));
5884 /* Go to LABEL if ADDR (a legitimate address expression)
5885 has an effect that depends on the machine mode it is used for.
5887 On the RS/6000 this is true of all integral offsets (since AltiVec
5888 and VSX modes don't allow them) or is a pre-increment or decrement.
5890 ??? Except that due to conceptual problems in offsettable_address_p
5891 we can't really report the problems of integral offsets. So leave
5892 this assuming that the adjustable offset must be valid for the
5893 sub-words of a TFmode operand, which is what we had before. */
5896 rs6000_mode_dependent_address (rtx addr)
5898 switch (GET_CODE (addr))
5901 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5902 is considered a legitimate address before reload, so there
5903 are no offset restrictions in that case. Note that this
5904 condition is safe in strict mode because any address involving
5905 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5906 been rejected as illegitimate. */
5907 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5908 && XEXP (addr, 0) != arg_pointer_rtx
5909 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5911 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5912 return val + 12 + 0x8000 >= 0x10000;
5919 /* Auto-increment cases are now treated generically in recog.c. */
5921 return TARGET_UPDATE;
5923 /* AND is only allowed in Altivec loads. */
5934 /* Debug version of rs6000_mode_dependent_address. */
5936 rs6000_debug_mode_dependent_address (rtx addr)
5938 bool ret = rs6000_mode_dependent_address (addr);
5940 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5941 ret ? "true" : "false");
5947 /* Implement FIND_BASE_TERM. */
5950 rs6000_find_base_term (rtx op)
5954 split_const (op, &base, &offset);
5955 if (GET_CODE (base) == UNSPEC)
5956 switch (XINT (base, 1))
5959 case UNSPEC_MACHOPIC_OFFSET:
5960 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5961 for aliasing purposes. */
5962 return XVECEXP (base, 0, 0);
5968 /* More elaborate version of recog's offsettable_memref_p predicate
5969 that works around the ??? note of rs6000_mode_dependent_address.
5970 In particular it accepts
5972 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5974 in 32-bit mode, that the recog predicate rejects. */
5977 rs6000_offsettable_memref_p (rtx op)
5982 /* First mimic offsettable_memref_p. */
5983 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5986 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5987 the latter predicate knows nothing about the mode of the memory
5988 reference and, therefore, assumes that it is the largest supported
5989 mode (TFmode). As a consequence, legitimate offsettable memory
5990 references are rejected. rs6000_legitimate_offset_address_p contains
5991 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5992 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5995 /* Change register usage conditional on target flags. */
5997 rs6000_conditional_register_usage (void)
6001 /* Set MQ register fixed (already call_used) if not POWER
6002 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6007 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6009 fixed_regs[13] = call_used_regs[13]
6010 = call_really_used_regs[13] = 1;
6012 /* Conditionally disable FPRs. */
6013 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6014 for (i = 32; i < 64; i++)
6015 fixed_regs[i] = call_used_regs[i]
6016 = call_really_used_regs[i] = 1;
6018 /* The TOC register is not killed across calls in a way that is
6019 visible to the compiler. */
6020 if (DEFAULT_ABI == ABI_AIX)
6021 call_really_used_regs[2] = 0;
6023 if (DEFAULT_ABI == ABI_V4
6024 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6026 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6028 if (DEFAULT_ABI == ABI_V4
6029 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6031 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6032 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6033 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6035 if (DEFAULT_ABI == ABI_DARWIN
6036 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6037 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6038 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6039 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6041 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6042 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6043 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6047 global_regs[SPEFSCR_REGNO] = 1;
6048 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6049 registers in prologues and epilogues. We no longer use r14
6050 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6051 pool for link-compatibility with older versions of GCC. Once
6052 "old" code has died out, we can return r14 to the allocation
6055 = call_used_regs[14]
6056 = call_really_used_regs[14] = 1;
6059 if (!TARGET_ALTIVEC && !TARGET_VSX)
6061 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6062 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6063 call_really_used_regs[VRSAVE_REGNO] = 1;
6066 if (TARGET_ALTIVEC || TARGET_VSX)
6067 global_regs[VSCR_REGNO] = 1;
6069 if (TARGET_ALTIVEC_ABI)
6071 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6072 call_used_regs[i] = call_really_used_regs[i] = 1;
6074 /* AIX reserves VR20:31 in non-extended ABI mode. */
6076 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6077 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6081 /* Try to output insns to set TARGET equal to the constant C if it can
6082 be done in less than N insns. Do all computations in MODE.
6083 Returns the place where the output has been placed if it can be
6084 done and the insns have been emitted. If it would take more than N
6085 insns, zero is returned and no insns and emitted. */
6088 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6089 rtx source, int n ATTRIBUTE_UNUSED)
6091 rtx result, insn, set;
6092 HOST_WIDE_INT c0, c1;
6099 dest = gen_reg_rtx (mode);
6100 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6104 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6106 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6107 GEN_INT (INTVAL (source)
6108 & (~ (HOST_WIDE_INT) 0xffff))));
6109 emit_insn (gen_rtx_SET (VOIDmode, dest,
6110 gen_rtx_IOR (SImode, copy_rtx (result),
6111 GEN_INT (INTVAL (source) & 0xffff))));
6116 switch (GET_CODE (source))
6119 c0 = INTVAL (source);
6124 #if HOST_BITS_PER_WIDE_INT >= 64
6125 c0 = CONST_DOUBLE_LOW (source);
6128 c0 = CONST_DOUBLE_LOW (source);
6129 c1 = CONST_DOUBLE_HIGH (source);
6137 result = rs6000_emit_set_long_const (dest, c0, c1);
6144 insn = get_last_insn ();
6145 set = single_set (insn);
6146 if (! CONSTANT_P (SET_SRC (set)))
6147 set_unique_reg_note (insn, REG_EQUAL, source);
6152 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6153 fall back to a straight forward decomposition. We do this to avoid
6154 exponential run times encountered when looking for longer sequences
6155 with rs6000_emit_set_const. */
6157 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6159 if (!TARGET_POWERPC64)
6161 rtx operand1, operand2;
6163 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6165 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6167 emit_move_insn (operand1, GEN_INT (c1));
6168 emit_move_insn (operand2, GEN_INT (c2));
6172 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6175 ud2 = (c1 & 0xffff0000) >> 16;
6176 #if HOST_BITS_PER_WIDE_INT >= 64
6180 ud4 = (c2 & 0xffff0000) >> 16;
6182 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6183 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6186 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6188 emit_move_insn (dest, GEN_INT (ud1));
6191 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6192 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6195 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6198 emit_move_insn (dest, GEN_INT (ud2 << 16));
6200 emit_move_insn (copy_rtx (dest),
6201 gen_rtx_IOR (DImode, copy_rtx (dest),
6204 else if (ud3 == 0 && ud4 == 0)
6206 gcc_assert (ud2 & 0x8000);
6207 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6210 emit_move_insn (copy_rtx (dest),
6211 gen_rtx_IOR (DImode, copy_rtx (dest),
6213 emit_move_insn (copy_rtx (dest),
6214 gen_rtx_ZERO_EXTEND (DImode,
6215 gen_lowpart (SImode,
6218 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6219 || (ud4 == 0 && ! (ud3 & 0x8000)))
6222 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6225 emit_move_insn (dest, GEN_INT (ud3 << 16));
6228 emit_move_insn (copy_rtx (dest),
6229 gen_rtx_IOR (DImode, copy_rtx (dest),
6231 emit_move_insn (copy_rtx (dest),
6232 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6235 emit_move_insn (copy_rtx (dest),
6236 gen_rtx_IOR (DImode, copy_rtx (dest),
6242 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6245 emit_move_insn (dest, GEN_INT (ud4 << 16));
6248 emit_move_insn (copy_rtx (dest),
6249 gen_rtx_IOR (DImode, copy_rtx (dest),
6252 emit_move_insn (copy_rtx (dest),
6253 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6256 emit_move_insn (copy_rtx (dest),
6257 gen_rtx_IOR (DImode, copy_rtx (dest),
6258 GEN_INT (ud2 << 16)));
6260 emit_move_insn (copy_rtx (dest),
6261 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6267 /* Helper for the following. Get rid of [r+r] memory refs
6268 in cases where it won't work (TImode, TFmode, TDmode). */
6271 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6273 if (GET_CODE (operands[0]) == MEM
6274 && GET_CODE (XEXP (operands[0], 0)) != REG
6275 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6276 && ! reload_in_progress)
6278 = replace_equiv_address (operands[0],
6279 copy_addr_to_reg (XEXP (operands[0], 0)));
6281 if (GET_CODE (operands[1]) == MEM
6282 && GET_CODE (XEXP (operands[1], 0)) != REG
6283 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6284 && ! reload_in_progress)
6286 = replace_equiv_address (operands[1],
6287 copy_addr_to_reg (XEXP (operands[1], 0)));
6290 /* Emit a move from SOURCE to DEST in mode MODE. */
6292 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6296 operands[1] = source;
6298 if (TARGET_DEBUG_ADDR)
6301 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6302 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6303 GET_MODE_NAME (mode),
6306 can_create_pseudo_p ());
6308 fprintf (stderr, "source:\n");
6312 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6313 if (GET_CODE (operands[1]) == CONST_DOUBLE
6314 && ! FLOAT_MODE_P (mode)
6315 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6317 /* FIXME. This should never happen. */
6318 /* Since it seems that it does, do the safe thing and convert
6320 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6322 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6323 || FLOAT_MODE_P (mode)
6324 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6325 || CONST_DOUBLE_LOW (operands[1]) < 0)
6326 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6327 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6329 /* Check if GCC is setting up a block move that will end up using FP
6330 registers as temporaries. We must make sure this is acceptable. */
6331 if (GET_CODE (operands[0]) == MEM
6332 && GET_CODE (operands[1]) == MEM
6334 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6335 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6336 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6337 ? 32 : MEM_ALIGN (operands[0])))
6338 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6340 : MEM_ALIGN (operands[1]))))
6341 && ! MEM_VOLATILE_P (operands [0])
6342 && ! MEM_VOLATILE_P (operands [1]))
6344 emit_move_insn (adjust_address (operands[0], SImode, 0),
6345 adjust_address (operands[1], SImode, 0));
6346 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6347 adjust_address (copy_rtx (operands[1]), SImode, 4));
6351 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6352 && !gpc_reg_operand (operands[1], mode))
6353 operands[1] = force_reg (mode, operands[1]);
6355 if (mode == SFmode && ! TARGET_POWERPC
6356 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6357 && GET_CODE (operands[0]) == MEM)
6361 if (reload_in_progress || reload_completed)
6362 regnum = true_regnum (operands[1]);
6363 else if (GET_CODE (operands[1]) == REG)
6364 regnum = REGNO (operands[1]);
6368 /* If operands[1] is a register, on POWER it may have
6369 double-precision data in it, so truncate it to single
6371 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6374 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6375 : gen_reg_rtx (mode));
6376 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6377 operands[1] = newreg;
6381 /* Recognize the case where operand[1] is a reference to thread-local
6382 data and load its address to a register. */
6383 if (rs6000_tls_referenced_p (operands[1]))
6385 enum tls_model model;
6386 rtx tmp = operands[1];
6389 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6391 addend = XEXP (XEXP (tmp, 0), 1);
6392 tmp = XEXP (XEXP (tmp, 0), 0);
6395 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6396 model = SYMBOL_REF_TLS_MODEL (tmp);
6397 gcc_assert (model != 0);
6399 tmp = rs6000_legitimize_tls_address (tmp, model);
6402 tmp = gen_rtx_PLUS (mode, tmp, addend);
6403 tmp = force_operand (tmp, operands[0]);
6408 /* Handle the case where reload calls us with an invalid address. */
6409 if (reload_in_progress && mode == Pmode
6410 && (! general_operand (operands[1], mode)
6411 || ! nonimmediate_operand (operands[0], mode)))
6414 /* 128-bit constant floating-point values on Darwin should really be
6415 loaded as two parts. */
6416 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6417 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6419 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6420 know how to get a DFmode SUBREG of a TFmode. */
6421 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6422 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6423 simplify_gen_subreg (imode, operands[1], mode, 0),
6425 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6426 GET_MODE_SIZE (imode)),
6427 simplify_gen_subreg (imode, operands[1], mode,
6428 GET_MODE_SIZE (imode)),
6433 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6434 cfun->machine->sdmode_stack_slot =
6435 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6437 if (reload_in_progress
6439 && MEM_P (operands[0])
6440 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6441 && REG_P (operands[1]))
6443 if (FP_REGNO_P (REGNO (operands[1])))
6445 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6446 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6447 emit_insn (gen_movsd_store (mem, operands[1]));
6449 else if (INT_REGNO_P (REGNO (operands[1])))
6451 rtx mem = adjust_address_nv (operands[0], mode, 4);
6452 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6453 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6459 if (reload_in_progress
6461 && REG_P (operands[0])
6462 && MEM_P (operands[1])
6463 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6465 if (FP_REGNO_P (REGNO (operands[0])))
6467 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6468 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6469 emit_insn (gen_movsd_load (operands[0], mem));
6471 else if (INT_REGNO_P (REGNO (operands[0])))
6473 rtx mem = adjust_address_nv (operands[1], mode, 4);
6474 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6475 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6482 /* FIXME: In the long term, this switch statement should go away
6483 and be replaced by a sequence of tests based on things like
6489 if (CONSTANT_P (operands[1])
6490 && GET_CODE (operands[1]) != CONST_INT)
6491 operands[1] = force_const_mem (mode, operands[1]);
6496 rs6000_eliminate_indexed_memrefs (operands);
6503 if (CONSTANT_P (operands[1])
6504 && ! easy_fp_constant (operands[1], mode))
6505 operands[1] = force_const_mem (mode, operands[1]);
6518 if (CONSTANT_P (operands[1])
6519 && !easy_vector_constant (operands[1], mode))
6520 operands[1] = force_const_mem (mode, operands[1]);
6525 /* Use default pattern for address of ELF small data */
6528 && DEFAULT_ABI == ABI_V4
6529 && (GET_CODE (operands[1]) == SYMBOL_REF
6530 || GET_CODE (operands[1]) == CONST)
6531 && small_data_operand (operands[1], mode))
6533 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6537 if (DEFAULT_ABI == ABI_V4
6538 && mode == Pmode && mode == SImode
6539 && flag_pic == 1 && got_operand (operands[1], mode))
6541 emit_insn (gen_movsi_got (operands[0], operands[1]));
6545 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6549 && CONSTANT_P (operands[1])
6550 && GET_CODE (operands[1]) != HIGH
6551 && GET_CODE (operands[1]) != CONST_INT)
6553 rtx target = (!can_create_pseudo_p ()
6555 : gen_reg_rtx (mode));
6557 /* If this is a function address on -mcall-aixdesc,
6558 convert it to the address of the descriptor. */
6559 if (DEFAULT_ABI == ABI_AIX
6560 && GET_CODE (operands[1]) == SYMBOL_REF
6561 && XSTR (operands[1], 0)[0] == '.')
6563 const char *name = XSTR (operands[1], 0);
6565 while (*name == '.')
6567 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6568 CONSTANT_POOL_ADDRESS_P (new_ref)
6569 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6570 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6571 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6572 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6573 operands[1] = new_ref;
6576 if (DEFAULT_ABI == ABI_DARWIN)
6579 if (MACHO_DYNAMIC_NO_PIC_P)
6581 /* Take care of any required data indirection. */
6582 operands[1] = rs6000_machopic_legitimize_pic_address (
6583 operands[1], mode, operands[0]);
6584 if (operands[0] != operands[1])
6585 emit_insn (gen_rtx_SET (VOIDmode,
6586 operands[0], operands[1]));
6590 emit_insn (gen_macho_high (target, operands[1]));
6591 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6595 emit_insn (gen_elf_high (target, operands[1]));
6596 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6600 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6601 and we have put it in the TOC, we just need to make a TOC-relative
6604 && GET_CODE (operands[1]) == SYMBOL_REF
6605 && constant_pool_expr_p (operands[1])
6606 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6607 get_pool_mode (operands[1])))
6609 operands[1] = create_TOC_reference (operands[1]);
6611 else if (mode == Pmode
6612 && CONSTANT_P (operands[1])
6613 && ((GET_CODE (operands[1]) != CONST_INT
6614 && ! easy_fp_constant (operands[1], mode))
6615 || (GET_CODE (operands[1]) == CONST_INT
6616 && num_insns_constant (operands[1], mode) > 2)
6617 || (GET_CODE (operands[0]) == REG
6618 && FP_REGNO_P (REGNO (operands[0]))))
6619 && GET_CODE (operands[1]) != HIGH
6620 && ! legitimate_constant_pool_address_p (operands[1])
6621 && ! toc_relative_expr_p (operands[1]))
6625 /* Darwin uses a special PIC legitimizer. */
6626 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6629 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6631 if (operands[0] != operands[1])
6632 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6637 /* If we are to limit the number of things we put in the TOC and
6638 this is a symbol plus a constant we can add in one insn,
6639 just put the symbol in the TOC and add the constant. Don't do
6640 this if reload is in progress. */
6641 if (GET_CODE (operands[1]) == CONST
6642 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6643 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6644 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6645 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6646 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6647 && ! side_effects_p (operands[0]))
6650 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6651 rtx other = XEXP (XEXP (operands[1], 0), 1);
6653 sym = force_reg (mode, sym);
6654 emit_insn (gen_add3_insn (operands[0], sym, other));
6658 operands[1] = force_const_mem (mode, operands[1]);
6661 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6662 && constant_pool_expr_p (XEXP (operands[1], 0))
6663 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6664 get_pool_constant (XEXP (operands[1], 0)),
6665 get_pool_mode (XEXP (operands[1], 0))))
6668 = gen_const_mem (mode,
6669 create_TOC_reference (XEXP (operands[1], 0)));
6670 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6676 rs6000_eliminate_indexed_memrefs (operands);
6680 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6682 gen_rtx_SET (VOIDmode,
6683 operands[0], operands[1]),
6684 gen_rtx_CLOBBER (VOIDmode,
6685 gen_rtx_SCRATCH (SImode)))));
6691 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6694 /* Above, we may have called force_const_mem which may have returned
6695 an invalid address. If we can, fix this up; otherwise, reload will
6696 have to deal with it. */
6697 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6698 operands[1] = validize_mem (operands[1]);
6701 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6704 /* Nonzero if we can use a floating-point register to pass this arg. */
6705 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6706 (SCALAR_FLOAT_MODE_P (MODE) \
6707 && (CUM)->fregno <= FP_ARG_MAX_REG \
6708 && TARGET_HARD_FLOAT && TARGET_FPRS)
6710 /* Nonzero if we can use an AltiVec register to pass this arg. */
6711 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6712 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6713 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6714 && TARGET_ALTIVEC_ABI \
6717 /* Return a nonzero value to say to return the function value in
6718 memory, just as large structures are always returned. TYPE will be
6719 the data type of the value, and FNTYPE will be the type of the
6720 function doing the returning, or @code{NULL} for libcalls.
6722 The AIX ABI for the RS/6000 specifies that all structures are
6723 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6724 specifies that structures <= 8 bytes are returned in r3/r4, but a
6725 draft put them in memory, and GCC used to implement the draft
6726 instead of the final standard. Therefore, aix_struct_return
6727 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6728 compatibility can change DRAFT_V4_STRUCT_RET to override the
6729 default, and -m switches get the final word. See
6730 rs6000_override_options for more details.
6732 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6733 long double support is enabled. These values are returned in memory.
6735 int_size_in_bytes returns -1 for variable size objects, which go in
6736 memory always. The cast to unsigned makes -1 > 8. */
6739 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6741 /* In the darwin64 abi, try to use registers for larger structs
6743 if (rs6000_darwin64_abi
6744 && TREE_CODE (type) == RECORD_TYPE
6745 && int_size_in_bytes (type) > 0)
6747 CUMULATIVE_ARGS valcum;
6751 valcum.fregno = FP_ARG_MIN_REG;
6752 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6753 /* Do a trial code generation as if this were going to be passed
6754 as an argument; if any part goes in memory, we return NULL. */
6755 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6758 /* Otherwise fall through to more conventional ABI rules. */
6761 if (AGGREGATE_TYPE_P (type)
6762 && (aix_struct_return
6763 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6766 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6767 modes only exist for GCC vector types if -maltivec. */
6768 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6769 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6772 /* Return synthetic vectors in memory. */
6773 if (TREE_CODE (type) == VECTOR_TYPE
6774 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6776 static bool warned_for_return_big_vectors = false;
6777 if (!warned_for_return_big_vectors)
6779 warning (0, "GCC vector returned by reference: "
6780 "non-standard ABI extension with no compatibility guarantee");
6781 warned_for_return_big_vectors = true;
6786 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6792 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6793 for a call to a function whose data type is FNTYPE.
6794 For a library call, FNTYPE is 0.
6796 For incoming args we set the number of arguments in the prototype large
6797 so we never return a PARALLEL. */
6800 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6801 rtx libname ATTRIBUTE_UNUSED, int incoming,
6802 int libcall, int n_named_args)
6804 static CUMULATIVE_ARGS zero_cumulative;
6806 *cum = zero_cumulative;
6808 cum->fregno = FP_ARG_MIN_REG;
6809 cum->vregno = ALTIVEC_ARG_MIN_REG;
6810 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6811 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6812 ? CALL_LIBCALL : CALL_NORMAL);
6813 cum->sysv_gregno = GP_ARG_MIN_REG;
6814 cum->stdarg = fntype
6815 && (TYPE_ARG_TYPES (fntype) != 0
6816 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6817 != void_type_node));
6819 cum->nargs_prototype = 0;
6820 if (incoming || cum->prototype)
6821 cum->nargs_prototype = n_named_args;
6823 /* Check for a longcall attribute. */
6824 if ((!fntype && rs6000_default_long_calls)
6826 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6827 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6828 cum->call_cookie |= CALL_LONG;
6830 if (TARGET_DEBUG_ARG)
6832 fprintf (stderr, "\ninit_cumulative_args:");
6835 tree ret_type = TREE_TYPE (fntype);
6836 fprintf (stderr, " ret code = %s,",
6837 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6840 if (cum->call_cookie & CALL_LONG)
6841 fprintf (stderr, " longcall,");
6843 fprintf (stderr, " proto = %d, nargs = %d\n",
6844 cum->prototype, cum->nargs_prototype);
6849 && TARGET_ALTIVEC_ABI
6850 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6852 error ("cannot return value in vector register because"
6853 " altivec instructions are disabled, use -maltivec"
6858 /* Return true if TYPE must be passed on the stack and not in registers. */
6861 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6863 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6864 return must_pass_in_stack_var_size (mode, type);
6866 return must_pass_in_stack_var_size_or_pad (mode, type);
6869 /* If defined, a C expression which determines whether, and in which
6870 direction, to pad out an argument with extra space. The value
6871 should be of type `enum direction': either `upward' to pad above
6872 the argument, `downward' to pad below, or `none' to inhibit
6875 For the AIX ABI structs are always stored left shifted in their
6879 function_arg_padding (enum machine_mode mode, const_tree type)
6881 #ifndef AGGREGATE_PADDING_FIXED
6882 #define AGGREGATE_PADDING_FIXED 0
6884 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6885 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6888 if (!AGGREGATE_PADDING_FIXED)
6890 /* GCC used to pass structures of the same size as integer types as
6891 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6892 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6893 passed padded downward, except that -mstrict-align further
6894 muddied the water in that multi-component structures of 2 and 4
6895 bytes in size were passed padded upward.
6897 The following arranges for best compatibility with previous
6898 versions of gcc, but removes the -mstrict-align dependency. */
6899 if (BYTES_BIG_ENDIAN)
6901 HOST_WIDE_INT size = 0;
6903 if (mode == BLKmode)
6905 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6906 size = int_size_in_bytes (type);
6909 size = GET_MODE_SIZE (mode);
6911 if (size == 1 || size == 2 || size == 4)
6917 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6919 if (type != 0 && AGGREGATE_TYPE_P (type))
6923 /* Fall back to the default. */
6924 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6927 /* If defined, a C expression that gives the alignment boundary, in bits,
6928 of an argument with the specified mode and type. If it is not defined,
6929 PARM_BOUNDARY is used for all arguments.
6931 V.4 wants long longs and doubles to be double word aligned. Just
6932 testing the mode size is a boneheaded way to do this as it means
6933 that other types such as complex int are also double word aligned.
6934 However, we're stuck with this because changing the ABI might break
6935 existing library interfaces.
6937 Doubleword align SPE vectors.
6938 Quadword align Altivec vectors.
6939 Quadword align large synthetic vector types. */
6942 function_arg_boundary (enum machine_mode mode, tree type)
6944 if (DEFAULT_ABI == ABI_V4
6945 && (GET_MODE_SIZE (mode) == 8
6946 || (TARGET_HARD_FLOAT
6948 && (mode == TFmode || mode == TDmode))))
6950 else if (SPE_VECTOR_MODE (mode)
6951 || (type && TREE_CODE (type) == VECTOR_TYPE
6952 && int_size_in_bytes (type) >= 8
6953 && int_size_in_bytes (type) < 16))
6955 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6956 || (type && TREE_CODE (type) == VECTOR_TYPE
6957 && int_size_in_bytes (type) >= 16))
6959 else if (rs6000_darwin64_abi && mode == BLKmode
6960 && type && TYPE_ALIGN (type) > 64)
6963 return PARM_BOUNDARY;
6966 /* For a function parm of MODE and TYPE, return the starting word in
6967 the parameter area. NWORDS of the parameter area are already used. */
6970 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6973 unsigned int parm_offset;
6975 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6976 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6977 return nwords + (-(parm_offset + nwords) & align);
6980 /* Compute the size (in words) of a function argument. */
6982 static unsigned long
6983 rs6000_arg_size (enum machine_mode mode, tree type)
6987 if (mode != BLKmode)
6988 size = GET_MODE_SIZE (mode);
6990 size = int_size_in_bytes (type);
6993 return (size + 3) >> 2;
6995 return (size + 7) >> 3;
6998 /* Use this to flush pending int fields. */
7001 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7002 HOST_WIDE_INT bitpos)
7004 unsigned int startbit, endbit;
7005 int intregs, intoffset;
7006 enum machine_mode mode;
7008 if (cum->intoffset == -1)
7011 intoffset = cum->intoffset;
7012 cum->intoffset = -1;
7014 if (intoffset % BITS_PER_WORD != 0)
7016 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7018 if (mode == BLKmode)
7020 /* We couldn't find an appropriate mode, which happens,
7021 e.g., in packed structs when there are 3 bytes to load.
7022 Back intoffset back to the beginning of the word in this
7024 intoffset = intoffset & -BITS_PER_WORD;
7028 startbit = intoffset & -BITS_PER_WORD;
7029 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7030 intregs = (endbit - startbit) / BITS_PER_WORD;
7031 cum->words += intregs;
7034 /* The darwin64 ABI calls for us to recurse down through structs,
7035 looking for elements passed in registers. Unfortunately, we have
7036 to track int register count here also because of misalignments
7037 in powerpc alignment mode. */
7040 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7042 HOST_WIDE_INT startbitpos)
7046 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7047 if (TREE_CODE (f) == FIELD_DECL)
7049 HOST_WIDE_INT bitpos = startbitpos;
7050 tree ftype = TREE_TYPE (f);
7051 enum machine_mode mode;
7052 if (ftype == error_mark_node)
7054 mode = TYPE_MODE (ftype);
7056 if (DECL_SIZE (f) != 0
7057 && host_integerp (bit_position (f), 1))
7058 bitpos += int_bit_position (f);
7060 /* ??? FIXME: else assume zero offset. */
7062 if (TREE_CODE (ftype) == RECORD_TYPE)
7063 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7064 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7066 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7067 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7068 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7070 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7072 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7076 else if (cum->intoffset == -1)
7077 cum->intoffset = bitpos;
7081 /* Update the data in CUM to advance over an argument
7082 of mode MODE and data type TYPE.
7083 (TYPE is null for libcalls where that information may not be available.)
7085 Note that for args passed by reference, function_arg will be called
7086 with MODE and TYPE set to that of the pointer to the arg, not the arg
7090 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7091 tree type, int named, int depth)
7095 /* Only tick off an argument if we're not recursing. */
7097 cum->nargs_prototype--;
7099 if (TARGET_ALTIVEC_ABI
7100 && (ALTIVEC_VECTOR_MODE (mode)
7101 || VSX_VECTOR_MODE (mode)
7102 || (type && TREE_CODE (type) == VECTOR_TYPE
7103 && int_size_in_bytes (type) == 16)))
7107 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7110 if (!TARGET_ALTIVEC)
7111 error ("cannot pass argument in vector register because"
7112 " altivec instructions are disabled, use -maltivec"
7115 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7116 even if it is going to be passed in a vector register.
7117 Darwin does the same for variable-argument functions. */
7118 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7119 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7129 /* Vector parameters must be 16-byte aligned. This places
7130 them at 2 mod 4 in terms of words in 32-bit mode, since
7131 the parameter save area starts at offset 24 from the
7132 stack. In 64-bit mode, they just have to start on an
7133 even word, since the parameter save area is 16-byte
7134 aligned. Space for GPRs is reserved even if the argument
7135 will be passed in memory. */
7137 align = (2 - cum->words) & 3;
7139 align = cum->words & 1;
7140 cum->words += align + rs6000_arg_size (mode, type);
7142 if (TARGET_DEBUG_ARG)
7144 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7146 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7147 cum->nargs_prototype, cum->prototype,
7148 GET_MODE_NAME (mode));
7152 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7154 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7157 else if (rs6000_darwin64_abi
7159 && TREE_CODE (type) == RECORD_TYPE
7160 && (size = int_size_in_bytes (type)) > 0)
7162 /* Variable sized types have size == -1 and are
7163 treated as if consisting entirely of ints.
7164 Pad to 16 byte boundary if needed. */
7165 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7166 && (cum->words % 2) != 0)
7168 /* For varargs, we can just go up by the size of the struct. */
7170 cum->words += (size + 7) / 8;
7173 /* It is tempting to say int register count just goes up by
7174 sizeof(type)/8, but this is wrong in a case such as
7175 { int; double; int; } [powerpc alignment]. We have to
7176 grovel through the fields for these too. */
7178 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7179 rs6000_darwin64_record_arg_advance_flush (cum,
7180 size * BITS_PER_UNIT);
7183 else if (DEFAULT_ABI == ABI_V4)
7185 if (TARGET_HARD_FLOAT && TARGET_FPRS
7186 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7187 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7188 || (mode == TFmode && !TARGET_IEEEQUAD)
7189 || mode == SDmode || mode == DDmode || mode == TDmode))
7191 /* _Decimal128 must use an even/odd register pair. This assumes
7192 that the register number is odd when fregno is odd. */
7193 if (mode == TDmode && (cum->fregno % 2) == 1)
7196 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7197 <= FP_ARG_V4_MAX_REG)
7198 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7201 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7202 if (mode == DFmode || mode == TFmode
7203 || mode == DDmode || mode == TDmode)
7204 cum->words += cum->words & 1;
7205 cum->words += rs6000_arg_size (mode, type);
7210 int n_words = rs6000_arg_size (mode, type);
7211 int gregno = cum->sysv_gregno;
7213 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7214 (r7,r8) or (r9,r10). As does any other 2 word item such
7215 as complex int due to a historical mistake. */
7217 gregno += (1 - gregno) & 1;
7219 /* Multi-reg args are not split between registers and stack. */
7220 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7222 /* Long long and SPE vectors are aligned on the stack.
7223 So are other 2 word items such as complex int due to
7224 a historical mistake. */
7226 cum->words += cum->words & 1;
7227 cum->words += n_words;
7230 /* Note: continuing to accumulate gregno past when we've started
7231 spilling to the stack indicates the fact that we've started
7232 spilling to the stack to expand_builtin_saveregs. */
7233 cum->sysv_gregno = gregno + n_words;
7236 if (TARGET_DEBUG_ARG)
7238 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7239 cum->words, cum->fregno);
7240 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7241 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7242 fprintf (stderr, "mode = %4s, named = %d\n",
7243 GET_MODE_NAME (mode), named);
7248 int n_words = rs6000_arg_size (mode, type);
7249 int start_words = cum->words;
7250 int align_words = rs6000_parm_start (mode, type, start_words);
7252 cum->words = align_words + n_words;
7254 if (SCALAR_FLOAT_MODE_P (mode)
7255 && TARGET_HARD_FLOAT && TARGET_FPRS)
7257 /* _Decimal128 must be passed in an even/odd float register pair.
7258 This assumes that the register number is odd when fregno is
7260 if (mode == TDmode && (cum->fregno % 2) == 1)
7262 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7265 if (TARGET_DEBUG_ARG)
7267 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7268 cum->words, cum->fregno);
7269 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7270 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7271 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7272 named, align_words - start_words, depth);
7278 spe_build_register_parallel (enum machine_mode mode, int gregno)
7285 r1 = gen_rtx_REG (DImode, gregno);
7286 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7287 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7291 r1 = gen_rtx_REG (DImode, gregno);
7292 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7293 r3 = gen_rtx_REG (DImode, gregno + 2);
7294 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7295 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7298 r1 = gen_rtx_REG (DImode, gregno);
7299 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7300 r3 = gen_rtx_REG (DImode, gregno + 2);
7301 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7302 r5 = gen_rtx_REG (DImode, gregno + 4);
7303 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7304 r7 = gen_rtx_REG (DImode, gregno + 6);
7305 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7306 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7313 /* Determine where to put a SIMD argument on the SPE. */
7315 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7318 int gregno = cum->sysv_gregno;
7320 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7321 are passed and returned in a pair of GPRs for ABI compatibility. */
7322 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7323 || mode == DCmode || mode == TCmode))
7325 int n_words = rs6000_arg_size (mode, type);
7327 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7329 gregno += (1 - gregno) & 1;
7331 /* Multi-reg args are not split between registers and stack. */
7332 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7335 return spe_build_register_parallel (mode, gregno);
7339 int n_words = rs6000_arg_size (mode, type);
7341 /* SPE vectors are put in odd registers. */
7342 if (n_words == 2 && (gregno & 1) == 0)
7345 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7348 enum machine_mode m = SImode;
7350 r1 = gen_rtx_REG (m, gregno);
7351 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7352 r2 = gen_rtx_REG (m, gregno + 1);
7353 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7354 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7361 if (gregno <= GP_ARG_MAX_REG)
7362 return gen_rtx_REG (mode, gregno);
7368 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7369 structure between cum->intoffset and bitpos to integer registers. */
7372 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7373 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7375 enum machine_mode mode;
7377 unsigned int startbit, endbit;
7378 int this_regno, intregs, intoffset;
7381 if (cum->intoffset == -1)
7384 intoffset = cum->intoffset;
7385 cum->intoffset = -1;
7387 /* If this is the trailing part of a word, try to only load that
7388 much into the register. Otherwise load the whole register. Note
7389 that in the latter case we may pick up unwanted bits. It's not a
7390 problem at the moment but may wish to revisit. */
7392 if (intoffset % BITS_PER_WORD != 0)
7394 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7396 if (mode == BLKmode)
7398 /* We couldn't find an appropriate mode, which happens,
7399 e.g., in packed structs when there are 3 bytes to load.
7400 Back intoffset back to the beginning of the word in this
7402 intoffset = intoffset & -BITS_PER_WORD;
7409 startbit = intoffset & -BITS_PER_WORD;
7410 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7411 intregs = (endbit - startbit) / BITS_PER_WORD;
7412 this_regno = cum->words + intoffset / BITS_PER_WORD;
7414 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7417 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7421 intoffset /= BITS_PER_UNIT;
7424 regno = GP_ARG_MIN_REG + this_regno;
7425 reg = gen_rtx_REG (mode, regno);
7427 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7430 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7434 while (intregs > 0);
7437 /* Recursive workhorse for the following. */
7440 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7441 HOST_WIDE_INT startbitpos, rtx rvec[],
7446 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7447 if (TREE_CODE (f) == FIELD_DECL)
7449 HOST_WIDE_INT bitpos = startbitpos;
7450 tree ftype = TREE_TYPE (f);
7451 enum machine_mode mode;
7452 if (ftype == error_mark_node)
7454 mode = TYPE_MODE (ftype);
7456 if (DECL_SIZE (f) != 0
7457 && host_integerp (bit_position (f), 1))
7458 bitpos += int_bit_position (f);
7460 /* ??? FIXME: else assume zero offset. */
7462 if (TREE_CODE (ftype) == RECORD_TYPE)
7463 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7464 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7469 case SCmode: mode = SFmode; break;
7470 case DCmode: mode = DFmode; break;
7471 case TCmode: mode = TFmode; break;
7475 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7477 = gen_rtx_EXPR_LIST (VOIDmode,
7478 gen_rtx_REG (mode, cum->fregno++),
7479 GEN_INT (bitpos / BITS_PER_UNIT));
7480 if (mode == TFmode || mode == TDmode)
7483 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7485 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7487 = gen_rtx_EXPR_LIST (VOIDmode,
7488 gen_rtx_REG (mode, cum->vregno++),
7489 GEN_INT (bitpos / BITS_PER_UNIT));
7491 else if (cum->intoffset == -1)
7492 cum->intoffset = bitpos;
7496 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7497 the register(s) to be used for each field and subfield of a struct
7498 being passed by value, along with the offset of where the
7499 register's value may be found in the block. FP fields go in FP
7500 register, vector fields go in vector registers, and everything
7501 else goes in int registers, packed as in memory.
7503 This code is also used for function return values. RETVAL indicates
7504 whether this is the case.
7506 Much of this is taken from the SPARC V9 port, which has a similar
7507 calling convention. */
7510 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7511 int named, bool retval)
7513 rtx rvec[FIRST_PSEUDO_REGISTER];
7514 int k = 1, kbase = 1;
7515 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7516 /* This is a copy; modifications are not visible to our caller. */
7517 CUMULATIVE_ARGS copy_cum = *orig_cum;
7518 CUMULATIVE_ARGS *cum = ©_cum;
7520 /* Pad to 16 byte boundary if needed. */
7521 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7522 && (cum->words % 2) != 0)
7529 /* Put entries into rvec[] for individual FP and vector fields, and
7530 for the chunks of memory that go in int regs. Note we start at
7531 element 1; 0 is reserved for an indication of using memory, and
7532 may or may not be filled in below. */
7533 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7534 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7536 /* If any part of the struct went on the stack put all of it there.
7537 This hack is because the generic code for
7538 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7539 parts of the struct are not at the beginning. */
7543 return NULL_RTX; /* doesn't go in registers at all */
7545 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7547 if (k > 1 || cum->use_stack)
7548 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7553 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7556 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7560 rtx rvec[GP_ARG_NUM_REG + 1];
7562 if (align_words >= GP_ARG_NUM_REG)
7565 n_units = rs6000_arg_size (mode, type);
7567 /* Optimize the simple case where the arg fits in one gpr, except in
7568 the case of BLKmode due to assign_parms assuming that registers are
7569 BITS_PER_WORD wide. */
7571 || (n_units == 1 && mode != BLKmode))
7572 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7575 if (align_words + n_units > GP_ARG_NUM_REG)
7576 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7577 using a magic NULL_RTX component.
7578 This is not strictly correct. Only some of the arg belongs in
7579 memory, not all of it. However, the normal scheme using
7580 function_arg_partial_nregs can result in unusual subregs, eg.
7581 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7582 store the whole arg to memory is often more efficient than code
7583 to store pieces, and we know that space is available in the right
7584 place for the whole arg. */
7585 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7590 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7591 rtx off = GEN_INT (i++ * 4);
7592 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7594 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7596 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7599 /* Determine where to put an argument to a function.
7600 Value is zero to push the argument on the stack,
7601 or a hard register in which to store the argument.
7603 MODE is the argument's machine mode.
7604 TYPE is the data type of the argument (as a tree).
7605 This is null for libcalls where that information may
7607 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7608 the preceding args and about the function being called. It is
7609 not modified in this routine.
7610 NAMED is nonzero if this argument is a named parameter
7611 (otherwise it is an extra parameter matching an ellipsis).
7613 On RS/6000 the first eight words of non-FP are normally in registers
7614 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7615 Under V.4, the first 8 FP args are in registers.
7617 If this is floating-point and no prototype is specified, we use
7618 both an FP and integer register (or possibly FP reg and stack). Library
7619 functions (when CALL_LIBCALL is set) always have the proper types for args,
7620 so we can pass the FP value just in one register. emit_library_function
7621 doesn't support PARALLEL anyway.
7623 Note that for args passed by reference, function_arg will be called
7624 with MODE and TYPE set to that of the pointer to the arg, not the arg
7628 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7629 tree type, int named)
7631 enum rs6000_abi abi = DEFAULT_ABI;
7633 /* Return a marker to indicate whether CR1 needs to set or clear the
7634 bit that V.4 uses to say fp args were passed in registers.
7635 Assume that we don't need the marker for software floating point,
7636 or compiler generated library calls. */
7637 if (mode == VOIDmode)
7640 && (cum->call_cookie & CALL_LIBCALL) == 0
7642 || (cum->nargs_prototype < 0
7643 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7645 /* For the SPE, we need to crxor CR6 always. */
7647 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7648 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7649 return GEN_INT (cum->call_cookie
7650 | ((cum->fregno == FP_ARG_MIN_REG)
7651 ? CALL_V4_SET_FP_ARGS
7652 : CALL_V4_CLEAR_FP_ARGS));
7655 return GEN_INT (cum->call_cookie);
7658 if (rs6000_darwin64_abi && mode == BLKmode
7659 && TREE_CODE (type) == RECORD_TYPE)
7661 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7662 if (rslt != NULL_RTX)
7664 /* Else fall through to usual handling. */
7667 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7668 if (TARGET_64BIT && ! cum->prototype)
7670 /* Vector parameters get passed in vector register
7671 and also in GPRs or memory, in absence of prototype. */
7674 align_words = (cum->words + 1) & ~1;
7676 if (align_words >= GP_ARG_NUM_REG)
7682 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7684 return gen_rtx_PARALLEL (mode,
7686 gen_rtx_EXPR_LIST (VOIDmode,
7688 gen_rtx_EXPR_LIST (VOIDmode,
7689 gen_rtx_REG (mode, cum->vregno),
7693 return gen_rtx_REG (mode, cum->vregno);
7694 else if (TARGET_ALTIVEC_ABI
7695 && (ALTIVEC_VECTOR_MODE (mode)
7696 || VSX_VECTOR_MODE (mode)
7697 || (type && TREE_CODE (type) == VECTOR_TYPE
7698 && int_size_in_bytes (type) == 16)))
7700 if (named || abi == ABI_V4)
7704 /* Vector parameters to varargs functions under AIX or Darwin
7705 get passed in memory and possibly also in GPRs. */
7706 int align, align_words, n_words;
7707 enum machine_mode part_mode;
7709 /* Vector parameters must be 16-byte aligned. This places them at
7710 2 mod 4 in terms of words in 32-bit mode, since the parameter
7711 save area starts at offset 24 from the stack. In 64-bit mode,
7712 they just have to start on an even word, since the parameter
7713 save area is 16-byte aligned. */
7715 align = (2 - cum->words) & 3;
7717 align = cum->words & 1;
7718 align_words = cum->words + align;
7720 /* Out of registers? Memory, then. */
7721 if (align_words >= GP_ARG_NUM_REG)
7724 if (TARGET_32BIT && TARGET_POWERPC64)
7725 return rs6000_mixed_function_arg (mode, type, align_words);
7727 /* The vector value goes in GPRs. Only the part of the
7728 value in GPRs is reported here. */
7730 n_words = rs6000_arg_size (mode, type);
7731 if (align_words + n_words > GP_ARG_NUM_REG)
7732 /* Fortunately, there are only two possibilities, the value
7733 is either wholly in GPRs or half in GPRs and half not. */
7736 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7739 else if (TARGET_SPE_ABI && TARGET_SPE
7740 && (SPE_VECTOR_MODE (mode)
7741 || (TARGET_E500_DOUBLE && (mode == DFmode
7744 || mode == TCmode))))
7745 return rs6000_spe_function_arg (cum, mode, type);
7747 else if (abi == ABI_V4)
7749 if (TARGET_HARD_FLOAT && TARGET_FPRS
7750 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7751 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7752 || (mode == TFmode && !TARGET_IEEEQUAD)
7753 || mode == SDmode || mode == DDmode || mode == TDmode))
7755 /* _Decimal128 must use an even/odd register pair. This assumes
7756 that the register number is odd when fregno is odd. */
7757 if (mode == TDmode && (cum->fregno % 2) == 1)
7760 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7761 <= FP_ARG_V4_MAX_REG)
7762 return gen_rtx_REG (mode, cum->fregno);
7768 int n_words = rs6000_arg_size (mode, type);
7769 int gregno = cum->sysv_gregno;
7771 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7772 (r7,r8) or (r9,r10). As does any other 2 word item such
7773 as complex int due to a historical mistake. */
7775 gregno += (1 - gregno) & 1;
7777 /* Multi-reg args are not split between registers and stack. */
7778 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7781 if (TARGET_32BIT && TARGET_POWERPC64)
7782 return rs6000_mixed_function_arg (mode, type,
7783 gregno - GP_ARG_MIN_REG);
7784 return gen_rtx_REG (mode, gregno);
7789 int align_words = rs6000_parm_start (mode, type, cum->words);
7791 /* _Decimal128 must be passed in an even/odd float register pair.
7792 This assumes that the register number is odd when fregno is odd. */
7793 if (mode == TDmode && (cum->fregno % 2) == 1)
7796 if (USE_FP_FOR_ARG_P (cum, mode, type))
7798 rtx rvec[GP_ARG_NUM_REG + 1];
7802 enum machine_mode fmode = mode;
7803 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7805 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7807 /* Currently, we only ever need one reg here because complex
7808 doubles are split. */
7809 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7810 && (fmode == TFmode || fmode == TDmode));
7812 /* Long double or _Decimal128 split over regs and memory. */
7813 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7816 /* Do we also need to pass this arg in the parameter save
7819 && (cum->nargs_prototype <= 0
7820 || (DEFAULT_ABI == ABI_AIX
7822 && align_words >= GP_ARG_NUM_REG)));
7824 if (!needs_psave && mode == fmode)
7825 return gen_rtx_REG (fmode, cum->fregno);
7830 /* Describe the part that goes in gprs or the stack.
7831 This piece must come first, before the fprs. */
7832 if (align_words < GP_ARG_NUM_REG)
7834 unsigned long n_words = rs6000_arg_size (mode, type);
7836 if (align_words + n_words > GP_ARG_NUM_REG
7837 || (TARGET_32BIT && TARGET_POWERPC64))
7839 /* If this is partially on the stack, then we only
7840 include the portion actually in registers here. */
7841 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7844 if (align_words + n_words > GP_ARG_NUM_REG)
7845 /* Not all of the arg fits in gprs. Say that it
7846 goes in memory too, using a magic NULL_RTX
7847 component. Also see comment in
7848 rs6000_mixed_function_arg for why the normal
7849 function_arg_partial_nregs scheme doesn't work
7851 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7855 r = gen_rtx_REG (rmode,
7856 GP_ARG_MIN_REG + align_words);
7857 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7858 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7860 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7864 /* The whole arg fits in gprs. */
7865 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7866 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7870 /* It's entirely in memory. */
7871 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7874 /* Describe where this piece goes in the fprs. */
7875 r = gen_rtx_REG (fmode, cum->fregno);
7876 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7878 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7880 else if (align_words < GP_ARG_NUM_REG)
7882 if (TARGET_32BIT && TARGET_POWERPC64)
7883 return rs6000_mixed_function_arg (mode, type, align_words);
7885 if (mode == BLKmode)
7888 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7895 /* For an arg passed partly in registers and partly in memory, this is
7896 the number of bytes passed in registers. For args passed entirely in
7897 registers or entirely in memory, zero. When an arg is described by a
7898 PARALLEL, perhaps using more than one register type, this function
7899 returns the number of bytes used by the first element of the PARALLEL. */
7902 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7903 tree type, bool named)
7908 if (DEFAULT_ABI == ABI_V4)
7911 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7912 && cum->nargs_prototype >= 0)
7915 /* In this complicated case we just disable the partial_nregs code. */
7916 if (rs6000_darwin64_abi && mode == BLKmode
7917 && TREE_CODE (type) == RECORD_TYPE
7918 && int_size_in_bytes (type) > 0)
7921 align_words = rs6000_parm_start (mode, type, cum->words);
7923 if (USE_FP_FOR_ARG_P (cum, mode, type))
7925 /* If we are passing this arg in the fixed parameter save area
7926 (gprs or memory) as well as fprs, then this function should
7927 return the number of partial bytes passed in the parameter
7928 save area rather than partial bytes passed in fprs. */
7930 && (cum->nargs_prototype <= 0
7931 || (DEFAULT_ABI == ABI_AIX
7933 && align_words >= GP_ARG_NUM_REG)))
7935 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7936 > FP_ARG_MAX_REG + 1)
7937 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7938 else if (cum->nargs_prototype >= 0)
7942 if (align_words < GP_ARG_NUM_REG
7943 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7944 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7946 if (ret != 0 && TARGET_DEBUG_ARG)
7947 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7952 /* A C expression that indicates when an argument must be passed by
7953 reference. If nonzero for an argument, a copy of that argument is
7954 made in memory and a pointer to the argument is passed instead of
7955 the argument itself. The pointer is passed in whatever way is
7956 appropriate for passing a pointer to that type.
7958 Under V.4, aggregates and long double are passed by reference.
7960 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7961 reference unless the AltiVec vector extension ABI is in force.
7963 As an extension to all ABIs, variable sized types are passed by
7967 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7968 enum machine_mode mode, const_tree type,
7969 bool named ATTRIBUTE_UNUSED)
7971 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7973 if (TARGET_DEBUG_ARG)
7974 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7981 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7983 if (TARGET_DEBUG_ARG)
7984 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7988 if (int_size_in_bytes (type) < 0)
7990 if (TARGET_DEBUG_ARG)
7991 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7995 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7996 modes only exist for GCC vector types if -maltivec. */
7997 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7999 if (TARGET_DEBUG_ARG)
8000 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8004 /* Pass synthetic vectors in memory. */
8005 if (TREE_CODE (type) == VECTOR_TYPE
8006 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8008 static bool warned_for_pass_big_vectors = false;
8009 if (TARGET_DEBUG_ARG)
8010 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8011 if (!warned_for_pass_big_vectors)
8013 warning (0, "GCC vector passed by reference: "
8014 "non-standard ABI extension with no compatibility guarantee");
8015 warned_for_pass_big_vectors = true;
8024 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8027 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8032 for (i = 0; i < nregs; i++)
8034 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8035 if (reload_completed)
8037 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8040 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8041 i * GET_MODE_SIZE (reg_mode));
8044 tem = replace_equiv_address (tem, XEXP (tem, 0));
8048 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8052 /* Perform any needed actions needed for a function that is receiving a
8053 variable number of arguments.
8057 MODE and TYPE are the mode and type of the current parameter.
8059 PRETEND_SIZE is a variable that should be set to the amount of stack
8060 that must be pushed by the prolog to pretend that our caller pushed
8063 Normally, this macro will push all remaining incoming registers on the
8064 stack and set PRETEND_SIZE to the length of the registers pushed. */
8067 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8068 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8071 CUMULATIVE_ARGS next_cum;
8072 int reg_size = TARGET_32BIT ? 4 : 8;
8073 rtx save_area = NULL_RTX, mem;
8074 int first_reg_offset;
8077 /* Skip the last named argument. */
8079 function_arg_advance (&next_cum, mode, type, 1, 0);
8081 if (DEFAULT_ABI == ABI_V4)
8083 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8087 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8088 HOST_WIDE_INT offset = 0;
8090 /* Try to optimize the size of the varargs save area.
8091 The ABI requires that ap.reg_save_area is doubleword
8092 aligned, but we don't need to allocate space for all
8093 the bytes, only those to which we actually will save
8095 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8096 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8097 if (TARGET_HARD_FLOAT && TARGET_FPRS
8098 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8099 && cfun->va_list_fpr_size)
8102 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8103 * UNITS_PER_FP_WORD;
8104 if (cfun->va_list_fpr_size
8105 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8106 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8108 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8109 * UNITS_PER_FP_WORD;
8113 offset = -((first_reg_offset * reg_size) & ~7);
8114 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8116 gpr_reg_num = cfun->va_list_gpr_size;
8117 if (reg_size == 4 && (first_reg_offset & 1))
8120 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8123 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8125 - (int) (GP_ARG_NUM_REG * reg_size);
8127 if (gpr_size + fpr_size)
8130 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8131 gcc_assert (GET_CODE (reg_save_area) == MEM);
8132 reg_save_area = XEXP (reg_save_area, 0);
8133 if (GET_CODE (reg_save_area) == PLUS)
8135 gcc_assert (XEXP (reg_save_area, 0)
8136 == virtual_stack_vars_rtx);
8137 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8138 offset += INTVAL (XEXP (reg_save_area, 1));
8141 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8144 cfun->machine->varargs_save_offset = offset;
8145 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8150 first_reg_offset = next_cum.words;
8151 save_area = virtual_incoming_args_rtx;
8153 if (targetm.calls.must_pass_in_stack (mode, type))
8154 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8157 set = get_varargs_alias_set ();
8158 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8159 && cfun->va_list_gpr_size)
8161 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8163 if (va_list_gpr_counter_field)
8165 /* V4 va_list_gpr_size counts number of registers needed. */
8166 if (nregs > cfun->va_list_gpr_size)
8167 nregs = cfun->va_list_gpr_size;
8171 /* char * va_list instead counts number of bytes needed. */
8172 if (nregs > cfun->va_list_gpr_size / reg_size)
8173 nregs = cfun->va_list_gpr_size / reg_size;
8176 mem = gen_rtx_MEM (BLKmode,
8177 plus_constant (save_area,
8178 first_reg_offset * reg_size));
8179 MEM_NOTRAP_P (mem) = 1;
8180 set_mem_alias_set (mem, set);
8181 set_mem_align (mem, BITS_PER_WORD);
8183 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8187 /* Save FP registers if needed. */
8188 if (DEFAULT_ABI == ABI_V4
8189 && TARGET_HARD_FLOAT && TARGET_FPRS
8191 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8192 && cfun->va_list_fpr_size)
8194 int fregno = next_cum.fregno, nregs;
8195 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8196 rtx lab = gen_label_rtx ();
8197 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8198 * UNITS_PER_FP_WORD);
8201 (gen_rtx_SET (VOIDmode,
8203 gen_rtx_IF_THEN_ELSE (VOIDmode,
8204 gen_rtx_NE (VOIDmode, cr1,
8206 gen_rtx_LABEL_REF (VOIDmode, lab),
8210 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8211 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8213 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8215 plus_constant (save_area, off));
8216 MEM_NOTRAP_P (mem) = 1;
8217 set_mem_alias_set (mem, set);
8218 set_mem_align (mem, GET_MODE_ALIGNMENT (
8219 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8220 ? DFmode : SFmode));
8221 emit_move_insn (mem, gen_rtx_REG (
8222 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8223 ? DFmode : SFmode, fregno));
8230 /* Create the va_list data type. */
8233 rs6000_build_builtin_va_list (void)
8235 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8237 /* For AIX, prefer 'char *' because that's what the system
8238 header files like. */
8239 if (DEFAULT_ABI != ABI_V4)
8240 return build_pointer_type (char_type_node);
8242 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8243 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8244 get_identifier ("__va_list_tag"), record);
8246 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8247 unsigned_char_type_node);
8248 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8249 unsigned_char_type_node);
8250 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8252 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8253 get_identifier ("reserved"), short_unsigned_type_node);
8254 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8255 get_identifier ("overflow_arg_area"),
8257 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8258 get_identifier ("reg_save_area"),
8261 va_list_gpr_counter_field = f_gpr;
8262 va_list_fpr_counter_field = f_fpr;
8264 DECL_FIELD_CONTEXT (f_gpr) = record;
8265 DECL_FIELD_CONTEXT (f_fpr) = record;
8266 DECL_FIELD_CONTEXT (f_res) = record;
8267 DECL_FIELD_CONTEXT (f_ovf) = record;
8268 DECL_FIELD_CONTEXT (f_sav) = record;
8270 TREE_CHAIN (record) = type_decl;
8271 TYPE_NAME (record) = type_decl;
8272 TYPE_FIELDS (record) = f_gpr;
8273 TREE_CHAIN (f_gpr) = f_fpr;
8274 TREE_CHAIN (f_fpr) = f_res;
8275 TREE_CHAIN (f_res) = f_ovf;
8276 TREE_CHAIN (f_ovf) = f_sav;
8278 layout_type (record);
8280 /* The correct type is an array type of one element. */
8281 return build_array_type (record, build_index_type (size_zero_node));
8284 /* Implement va_start. */
8287 rs6000_va_start (tree valist, rtx nextarg)
8289 HOST_WIDE_INT words, n_gpr, n_fpr;
8290 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8291 tree gpr, fpr, ovf, sav, t;
8293 /* Only SVR4 needs something special. */
8294 if (DEFAULT_ABI != ABI_V4)
8296 std_expand_builtin_va_start (valist, nextarg);
8300 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8301 f_fpr = TREE_CHAIN (f_gpr);
8302 f_res = TREE_CHAIN (f_fpr);
8303 f_ovf = TREE_CHAIN (f_res);
8304 f_sav = TREE_CHAIN (f_ovf);
8306 valist = build_va_arg_indirect_ref (valist);
8307 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8308 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8310 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8312 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8315 /* Count number of gp and fp argument registers used. */
8316 words = crtl->args.info.words;
8317 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8319 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8322 if (TARGET_DEBUG_ARG)
8323 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8324 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8325 words, n_gpr, n_fpr);
8327 if (cfun->va_list_gpr_size)
8329 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8330 build_int_cst (NULL_TREE, n_gpr));
8331 TREE_SIDE_EFFECTS (t) = 1;
8332 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8335 if (cfun->va_list_fpr_size)
8337 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8338 build_int_cst (NULL_TREE, n_fpr));
8339 TREE_SIDE_EFFECTS (t) = 1;
8340 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8343 /* Find the overflow area. */
8344 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8346 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8347 size_int (words * UNITS_PER_WORD));
8348 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8349 TREE_SIDE_EFFECTS (t) = 1;
8350 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8352 /* If there were no va_arg invocations, don't set up the register
8354 if (!cfun->va_list_gpr_size
8355 && !cfun->va_list_fpr_size
8356 && n_gpr < GP_ARG_NUM_REG
8357 && n_fpr < FP_ARG_V4_MAX_REG)
8360 /* Find the register save area. */
8361 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8362 if (cfun->machine->varargs_save_offset)
8363 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8364 size_int (cfun->machine->varargs_save_offset));
8365 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8366 TREE_SIDE_EFFECTS (t) = 1;
8367 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8370 /* Implement va_arg. */
8373 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8376 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8377 tree gpr, fpr, ovf, sav, reg, t, u;
8378 int size, rsize, n_reg, sav_ofs, sav_scale;
8379 tree lab_false, lab_over, addr;
8381 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8385 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8387 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8388 return build_va_arg_indirect_ref (t);
8391 if (DEFAULT_ABI != ABI_V4)
8393 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8395 tree elem_type = TREE_TYPE (type);
8396 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8397 int elem_size = GET_MODE_SIZE (elem_mode);
8399 if (elem_size < UNITS_PER_WORD)
8401 tree real_part, imag_part;
8402 gimple_seq post = NULL;
8404 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8406 /* Copy the value into a temporary, lest the formal temporary
8407 be reused out from under us. */
8408 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8409 gimple_seq_add_seq (pre_p, post);
8411 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8414 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8418 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8421 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8422 f_fpr = TREE_CHAIN (f_gpr);
8423 f_res = TREE_CHAIN (f_fpr);
8424 f_ovf = TREE_CHAIN (f_res);
8425 f_sav = TREE_CHAIN (f_ovf);
8427 valist = build_va_arg_indirect_ref (valist);
8428 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8429 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8431 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8433 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8436 size = int_size_in_bytes (type);
8437 rsize = (size + 3) / 4;
8440 if (TARGET_HARD_FLOAT && TARGET_FPRS
8441 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8442 || (TARGET_DOUBLE_FLOAT
8443 && (TYPE_MODE (type) == DFmode
8444 || TYPE_MODE (type) == TFmode
8445 || TYPE_MODE (type) == SDmode
8446 || TYPE_MODE (type) == DDmode
8447 || TYPE_MODE (type) == TDmode))))
8449 /* FP args go in FP registers, if present. */
8451 n_reg = (size + 7) / 8;
8452 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8453 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8454 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8459 /* Otherwise into GP registers. */
8468 /* Pull the value out of the saved registers.... */
8471 addr = create_tmp_var (ptr_type_node, "addr");
8473 /* AltiVec vectors never go in registers when -mabi=altivec. */
8474 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8478 lab_false = create_artificial_label (input_location);
8479 lab_over = create_artificial_label (input_location);
8481 /* Long long and SPE vectors are aligned in the registers.
8482 As are any other 2 gpr item such as complex int due to a
8483 historical mistake. */
8485 if (n_reg == 2 && reg == gpr)
8488 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8489 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8490 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8491 unshare_expr (reg), u);
8493 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8494 reg number is 0 for f1, so we want to make it odd. */
8495 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8497 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8498 build_int_cst (TREE_TYPE (reg), 1));
8499 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8502 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8503 t = build2 (GE_EXPR, boolean_type_node, u, t);
8504 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8505 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8506 gimplify_and_add (t, pre_p);
8510 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8512 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8513 build_int_cst (TREE_TYPE (reg), n_reg));
8514 u = fold_convert (sizetype, u);
8515 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8516 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8518 /* _Decimal32 varargs are located in the second word of the 64-bit
8519 FP register for 32-bit binaries. */
8520 if (!TARGET_POWERPC64
8521 && TARGET_HARD_FLOAT && TARGET_FPRS
8522 && TYPE_MODE (type) == SDmode)
8523 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8525 gimplify_assign (addr, t, pre_p);
8527 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8529 stmt = gimple_build_label (lab_false);
8530 gimple_seq_add_stmt (pre_p, stmt);
8532 if ((n_reg == 2 && !regalign) || n_reg > 2)
8534 /* Ensure that we don't find any more args in regs.
8535 Alignment has taken care of for special cases. */
8536 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8540 /* ... otherwise out of the overflow area. */
8542 /* Care for on-stack alignment if needed. */
8546 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8547 t = fold_convert (sizetype, t);
8548 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8550 t = fold_convert (TREE_TYPE (ovf), t);
8552 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8554 gimplify_assign (unshare_expr (addr), t, pre_p);
8556 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8557 gimplify_assign (unshare_expr (ovf), t, pre_p);
8561 stmt = gimple_build_label (lab_over);
8562 gimple_seq_add_stmt (pre_p, stmt);
8565 if (STRICT_ALIGNMENT
8566 && (TYPE_ALIGN (type)
8567 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8569 /* The value (of type complex double, for example) may not be
8570 aligned in memory in the saved registers, so copy via a
8571 temporary. (This is the same code as used for SPARC.) */
8572 tree tmp = create_tmp_var (type, "va_arg_tmp");
8573 tree dest_addr = build_fold_addr_expr (tmp);
8575 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8576 3, dest_addr, addr, size_int (rsize * 4));
8578 gimplify_and_add (copy, pre_p);
8582 addr = fold_convert (ptrtype, addr);
8583 return build_va_arg_indirect_ref (addr);
8589 def_builtin (int mask, const char *name, tree type, int code)
8591 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8594 if (rs6000_builtin_decls[code])
8595 fatal_error ("internal error: builtin function to %s already processed.",
8598 rs6000_builtin_decls[code] = t =
8599 add_builtin_function (name, type, code, BUILT_IN_MD,
8602 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8603 switch (builtin_classify[code])
8608 /* assume builtin can do anything. */
8609 case RS6000_BTC_MISC:
8612 /* const function, function only depends on the inputs. */
8613 case RS6000_BTC_CONST:
8614 TREE_READONLY (t) = 1;
8615 TREE_NOTHROW (t) = 1;
8618 /* pure function, function can read global memory. */
8619 case RS6000_BTC_PURE:
8620 DECL_PURE_P (t) = 1;
8621 TREE_NOTHROW (t) = 1;
8624 /* Function is a math function. If rounding mode is on, then treat
8625 the function as not reading global memory, but it can have
8626 arbitrary side effects. If it is off, then assume the function is
8627 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8628 attribute in builtin-attribute.def that is used for the math
8630 case RS6000_BTC_FP_PURE:
8631 TREE_NOTHROW (t) = 1;
8632 if (flag_rounding_math)
8634 DECL_PURE_P (t) = 1;
8635 DECL_IS_NOVOPS (t) = 1;
8638 TREE_READONLY (t) = 1;
8644 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8646 static const struct builtin_description bdesc_3arg[] =
8648 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8649 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8650 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8669 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8670 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8671 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8672 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8673 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8674 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8675 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8676 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8677 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8678 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8684 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8692 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8693 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8697 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8698 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8700 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8701 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8702 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8703 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8705 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8706 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8707 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8708 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8713 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8714 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8715 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8716 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8717 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8718 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8719 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8720 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8721 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8722 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8724 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8725 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8726 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8727 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8728 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8729 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8730 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8731 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8732 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8733 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8735 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8736 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8737 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8738 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8739 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8740 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8741 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8742 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8743 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8745 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8746 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8747 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8748 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8749 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8750 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8751 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8753 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8754 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8755 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8756 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8757 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8758 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8759 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8760 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8761 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8764 /* DST operations: void foo (void *, const int, const char). */
8766 static const struct builtin_description bdesc_dst[] =
8768 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8769 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8770 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8771 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8779 /* Simple binary operations: VECc = foo (VECa, VECb). */
8781 static struct builtin_description bdesc_2arg[] =
8783 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8784 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8785 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8786 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8787 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8788 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8789 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8790 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8791 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8792 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8793 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8794 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8795 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8796 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8797 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8798 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8799 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8800 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8803 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8804 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8805 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8806 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8807 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8808 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8809 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8810 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8811 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8812 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8813 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8814 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8815 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8816 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8817 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8818 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8819 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8820 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8821 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8822 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8823 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8824 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8825 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8826 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8827 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8828 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8829 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8830 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8831 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8832 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8833 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8834 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8835 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8836 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8837 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8838 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8839 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8840 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8841 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8846 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8847 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8848 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8849 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8850 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8851 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8852 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8860 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8861 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8862 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8863 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8864 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8865 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8866 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8867 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8871 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8872 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8873 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8874 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8875 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8876 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8877 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8878 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8879 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8880 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8881 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8882 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8883 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8884 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8885 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8886 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8887 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8888 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8889 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8890 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8891 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8892 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8895 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8896 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8897 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8898 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8900 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8901 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8902 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8903 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8904 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8905 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8906 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8907 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8908 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8909 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8910 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8912 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8913 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8914 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8915 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8916 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8917 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8918 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8919 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8920 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8921 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8922 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8924 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8925 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8926 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8927 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8928 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8929 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8931 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8932 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8933 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8934 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8935 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8936 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8937 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8938 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8939 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8940 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8941 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8942 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8944 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8945 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8957 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8958 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8984 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8985 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9000 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9001 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9018 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9019 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9052 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9053 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9071 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9073 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9074 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9076 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9077 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9078 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9079 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9080 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9081 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9082 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9083 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9084 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9085 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9087 /* Place holder, leave as first spe builtin. */
9088 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9089 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9090 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9091 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9092 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9093 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9094 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9095 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9096 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9097 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9098 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9099 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9100 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9101 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9102 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9103 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9104 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9105 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9106 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9107 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9108 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9109 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9110 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9111 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9112 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9113 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9114 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9115 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9116 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9117 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9118 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9119 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9120 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9121 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9122 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9123 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9124 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9125 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9126 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9127 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9128 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9129 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9130 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9131 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9132 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9133 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9134 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9135 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9136 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9137 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9138 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9139 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9140 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9141 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9142 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9143 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9144 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9145 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9146 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9147 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9148 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9149 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9150 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9151 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9152 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9153 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9154 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9155 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9156 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9157 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9158 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9159 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9160 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9161 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9162 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9163 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9164 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9165 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9166 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9167 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9168 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9169 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9170 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9171 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9172 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9173 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9174 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9175 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9176 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9177 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9178 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9179 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9180 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9181 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9182 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9183 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9184 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9185 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9186 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9187 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9188 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9189 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9190 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9191 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9192 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9193 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9194 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9195 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9196 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9198 /* SPE binary operations expecting a 5-bit unsigned literal. */
9199 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9201 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9202 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9203 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9204 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9205 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9206 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9207 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9208 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9209 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9210 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9211 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9212 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9213 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9214 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9215 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9216 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9217 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9218 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9219 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9220 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9221 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9222 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9223 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9224 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9225 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9226 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9228 /* Place-holder. Leave as last binary SPE builtin. */
9229 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9232 /* AltiVec predicates. */
9234 struct builtin_description_predicates
9236 const unsigned int mask;
9237 const enum insn_code icode;
9238 const char *const name;
9239 const enum rs6000_builtins code;
9242 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9244 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9245 ALTIVEC_BUILTIN_VCMPBFP_P },
9246 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9247 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9248 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9249 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9250 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9251 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9252 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9253 ALTIVEC_BUILTIN_VCMPEQUW_P },
9254 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9255 ALTIVEC_BUILTIN_VCMPGTSW_P },
9256 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9257 ALTIVEC_BUILTIN_VCMPGTUW_P },
9258 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9259 ALTIVEC_BUILTIN_VCMPEQUH_P },
9260 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9261 ALTIVEC_BUILTIN_VCMPGTSH_P },
9262 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9263 ALTIVEC_BUILTIN_VCMPGTUH_P },
9264 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9265 ALTIVEC_BUILTIN_VCMPEQUB_P },
9266 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9267 ALTIVEC_BUILTIN_VCMPGTSB_P },
9268 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9269 ALTIVEC_BUILTIN_VCMPGTUB_P },
9271 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9272 VSX_BUILTIN_XVCMPEQSP_P },
9273 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9274 VSX_BUILTIN_XVCMPGESP_P },
9275 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9276 VSX_BUILTIN_XVCMPGTSP_P },
9277 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9278 VSX_BUILTIN_XVCMPEQDP_P },
9279 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9280 VSX_BUILTIN_XVCMPGEDP_P },
9281 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9282 VSX_BUILTIN_XVCMPGTDP_P },
9284 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9285 ALTIVEC_BUILTIN_VCMPEQ_P },
9286 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9287 ALTIVEC_BUILTIN_VCMPGT_P },
9288 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9289 ALTIVEC_BUILTIN_VCMPGE_P }
9292 /* SPE predicates. */
9293 static struct builtin_description bdesc_spe_predicates[] =
9295 /* Place-holder. Leave as first. */
9296 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9297 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9298 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9299 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9300 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9301 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9302 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9303 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9304 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9305 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9306 /* Place-holder. Leave as last. */
9307 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9310 /* SPE evsel predicates. */
9311 static struct builtin_description bdesc_spe_evsel[] =
9313 /* Place-holder. Leave as first. */
9314 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9315 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9316 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9317 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9318 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9319 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9320 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9321 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9322 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9323 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9324 /* Place-holder. Leave as last. */
9325 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9328 /* PAIRED predicates. */
9329 static const struct builtin_description bdesc_paired_preds[] =
9331 /* Place-holder. Leave as first. */
9332 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9333 /* Place-holder. Leave as last. */
9334 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9337 /* ABS* operations. */
9339 static const struct builtin_description bdesc_abs[] =
9341 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9342 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9343 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9344 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9345 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9346 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9347 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9348 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9349 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9350 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9351 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9354 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9357 static struct builtin_description bdesc_1arg[] =
9359 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9360 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9361 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9362 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9363 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9364 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9365 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9366 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9367 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9368 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9369 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9370 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9371 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9372 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9374 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9375 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9377 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9378 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9379 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9380 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9381 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9382 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9384 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9385 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9386 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9387 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9388 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9389 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9391 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9392 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9393 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9394 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9395 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9396 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9398 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9399 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9400 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9401 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9402 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9403 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9405 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9406 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9407 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9408 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9410 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9411 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9412 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9413 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9414 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9415 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9416 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9417 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9418 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9420 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9421 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9422 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9423 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9424 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9425 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9426 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9427 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9428 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9430 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9431 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9432 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9433 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9434 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9456 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9457 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9458 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9460 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9461 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9462 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9463 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9465 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9466 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9467 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9468 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9469 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9470 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9471 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9472 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9473 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9474 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9475 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9476 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9477 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9478 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9479 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9480 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9481 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9482 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9483 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9484 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9485 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9486 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9487 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9488 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9489 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9490 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9491 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9492 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9493 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9494 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9496 /* Place-holder. Leave as last unary SPE builtin. */
9497 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9499 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9500 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9501 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9502 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9503 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9507 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9510 tree arg0 = CALL_EXPR_ARG (exp, 0);
9511 rtx op0 = expand_normal (arg0);
9512 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9513 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9515 if (icode == CODE_FOR_nothing)
9516 /* Builtin not supported on this processor. */
9519 /* If we got invalid arguments bail out before generating bad rtl. */
9520 if (arg0 == error_mark_node)
9523 if (icode == CODE_FOR_altivec_vspltisb
9524 || icode == CODE_FOR_altivec_vspltish
9525 || icode == CODE_FOR_altivec_vspltisw
9526 || icode == CODE_FOR_spe_evsplatfi
9527 || icode == CODE_FOR_spe_evsplati)
9529 /* Only allow 5-bit *signed* literals. */
9530 if (GET_CODE (op0) != CONST_INT
9531 || INTVAL (op0) > 15
9532 || INTVAL (op0) < -16)
9534 error ("argument 1 must be a 5-bit signed literal");
9540 || GET_MODE (target) != tmode
9541 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9542 target = gen_reg_rtx (tmode);
9544 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9545 op0 = copy_to_mode_reg (mode0, op0);
9547 pat = GEN_FCN (icode) (target, op0);
9556 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9558 rtx pat, scratch1, scratch2;
9559 tree arg0 = CALL_EXPR_ARG (exp, 0);
9560 rtx op0 = expand_normal (arg0);
9561 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9562 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9564 /* If we have invalid arguments, bail out before generating bad rtl. */
9565 if (arg0 == error_mark_node)
9569 || GET_MODE (target) != tmode
9570 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9571 target = gen_reg_rtx (tmode);
9573 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9574 op0 = copy_to_mode_reg (mode0, op0);
9576 scratch1 = gen_reg_rtx (mode0);
9577 scratch2 = gen_reg_rtx (mode0);
9579 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9588 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9591 tree arg0 = CALL_EXPR_ARG (exp, 0);
9592 tree arg1 = CALL_EXPR_ARG (exp, 1);
9593 rtx op0 = expand_normal (arg0);
9594 rtx op1 = expand_normal (arg1);
9595 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9596 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9597 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9599 if (icode == CODE_FOR_nothing)
9600 /* Builtin not supported on this processor. */
9603 /* If we got invalid arguments bail out before generating bad rtl. */
9604 if (arg0 == error_mark_node || arg1 == error_mark_node)
9607 if (icode == CODE_FOR_altivec_vcfux
9608 || icode == CODE_FOR_altivec_vcfsx
9609 || icode == CODE_FOR_altivec_vctsxs
9610 || icode == CODE_FOR_altivec_vctuxs
9611 || icode == CODE_FOR_altivec_vspltb
9612 || icode == CODE_FOR_altivec_vsplth
9613 || icode == CODE_FOR_altivec_vspltw
9614 || icode == CODE_FOR_spe_evaddiw
9615 || icode == CODE_FOR_spe_evldd
9616 || icode == CODE_FOR_spe_evldh
9617 || icode == CODE_FOR_spe_evldw
9618 || icode == CODE_FOR_spe_evlhhesplat
9619 || icode == CODE_FOR_spe_evlhhossplat
9620 || icode == CODE_FOR_spe_evlhhousplat
9621 || icode == CODE_FOR_spe_evlwhe
9622 || icode == CODE_FOR_spe_evlwhos
9623 || icode == CODE_FOR_spe_evlwhou
9624 || icode == CODE_FOR_spe_evlwhsplat
9625 || icode == CODE_FOR_spe_evlwwsplat
9626 || icode == CODE_FOR_spe_evrlwi
9627 || icode == CODE_FOR_spe_evslwi
9628 || icode == CODE_FOR_spe_evsrwis
9629 || icode == CODE_FOR_spe_evsubifw
9630 || icode == CODE_FOR_spe_evsrwiu)
9632 /* Only allow 5-bit unsigned literals. */
9634 if (TREE_CODE (arg1) != INTEGER_CST
9635 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9637 error ("argument 2 must be a 5-bit unsigned literal");
9643 || GET_MODE (target) != tmode
9644 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9645 target = gen_reg_rtx (tmode);
9647 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9648 op0 = copy_to_mode_reg (mode0, op0);
9649 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9650 op1 = copy_to_mode_reg (mode1, op1);
9652 pat = GEN_FCN (icode) (target, op0, op1);
9661 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9664 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9665 tree arg0 = CALL_EXPR_ARG (exp, 1);
9666 tree arg1 = CALL_EXPR_ARG (exp, 2);
9667 rtx op0 = expand_normal (arg0);
9668 rtx op1 = expand_normal (arg1);
9669 enum machine_mode tmode = SImode;
9670 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9671 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9674 if (TREE_CODE (cr6_form) != INTEGER_CST)
9676 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9680 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9682 gcc_assert (mode0 == mode1);
9684 /* If we have invalid arguments, bail out before generating bad rtl. */
9685 if (arg0 == error_mark_node || arg1 == error_mark_node)
9689 || GET_MODE (target) != tmode
9690 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9691 target = gen_reg_rtx (tmode);
9693 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9694 op0 = copy_to_mode_reg (mode0, op0);
9695 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9696 op1 = copy_to_mode_reg (mode1, op1);
9698 scratch = gen_reg_rtx (mode0);
9700 pat = GEN_FCN (icode) (scratch, op0, op1);
9705 /* The vec_any* and vec_all* predicates use the same opcodes for two
9706 different operations, but the bits in CR6 will be different
9707 depending on what information we want. So we have to play tricks
9708 with CR6 to get the right bits out.
9710 If you think this is disgusting, look at the specs for the
9711 AltiVec predicates. */
9713 switch (cr6_form_int)
9716 emit_insn (gen_cr6_test_for_zero (target));
9719 emit_insn (gen_cr6_test_for_zero_reverse (target));
9722 emit_insn (gen_cr6_test_for_lt (target));
9725 emit_insn (gen_cr6_test_for_lt_reverse (target));
9728 error ("argument 1 of __builtin_altivec_predicate is out of range");
9736 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9739 tree arg0 = CALL_EXPR_ARG (exp, 0);
9740 tree arg1 = CALL_EXPR_ARG (exp, 1);
9741 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9742 enum machine_mode mode0 = Pmode;
9743 enum machine_mode mode1 = Pmode;
9744 rtx op0 = expand_normal (arg0);
9745 rtx op1 = expand_normal (arg1);
9747 if (icode == CODE_FOR_nothing)
9748 /* Builtin not supported on this processor. */
9751 /* If we got invalid arguments bail out before generating bad rtl. */
9752 if (arg0 == error_mark_node || arg1 == error_mark_node)
9756 || GET_MODE (target) != tmode
9757 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9758 target = gen_reg_rtx (tmode);
9760 op1 = copy_to_mode_reg (mode1, op1);
9762 if (op0 == const0_rtx)
9764 addr = gen_rtx_MEM (tmode, op1);
9768 op0 = copy_to_mode_reg (mode0, op0);
9769 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9772 pat = GEN_FCN (icode) (target, addr);
9782 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9785 tree arg0 = CALL_EXPR_ARG (exp, 0);
9786 tree arg1 = CALL_EXPR_ARG (exp, 1);
9787 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9788 enum machine_mode mode0 = Pmode;
9789 enum machine_mode mode1 = Pmode;
9790 rtx op0 = expand_normal (arg0);
9791 rtx op1 = expand_normal (arg1);
9793 if (icode == CODE_FOR_nothing)
9794 /* Builtin not supported on this processor. */
9797 /* If we got invalid arguments bail out before generating bad rtl. */
9798 if (arg0 == error_mark_node || arg1 == error_mark_node)
9802 || GET_MODE (target) != tmode
9803 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9804 target = gen_reg_rtx (tmode);
9806 op1 = copy_to_mode_reg (mode1, op1);
9808 if (op0 == const0_rtx)
9810 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9814 op0 = copy_to_mode_reg (mode0, op0);
9815 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9818 pat = GEN_FCN (icode) (target, addr);
9828 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9830 tree arg0 = CALL_EXPR_ARG (exp, 0);
9831 tree arg1 = CALL_EXPR_ARG (exp, 1);
9832 tree arg2 = CALL_EXPR_ARG (exp, 2);
9833 rtx op0 = expand_normal (arg0);
9834 rtx op1 = expand_normal (arg1);
9835 rtx op2 = expand_normal (arg2);
9837 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9838 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9839 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9841 /* Invalid arguments. Bail before doing anything stoopid! */
9842 if (arg0 == error_mark_node
9843 || arg1 == error_mark_node
9844 || arg2 == error_mark_node)
9847 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9848 op0 = copy_to_mode_reg (mode2, op0);
9849 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9850 op1 = copy_to_mode_reg (mode0, op1);
9851 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9852 op2 = copy_to_mode_reg (mode1, op2);
9854 pat = GEN_FCN (icode) (op1, op2, op0);
9861 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9863 tree arg0 = CALL_EXPR_ARG (exp, 0);
9864 tree arg1 = CALL_EXPR_ARG (exp, 1);
9865 tree arg2 = CALL_EXPR_ARG (exp, 2);
9866 rtx op0 = expand_normal (arg0);
9867 rtx op1 = expand_normal (arg1);
9868 rtx op2 = expand_normal (arg2);
9870 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9871 enum machine_mode mode1 = Pmode;
9872 enum machine_mode mode2 = Pmode;
9874 /* Invalid arguments. Bail before doing anything stoopid! */
9875 if (arg0 == error_mark_node
9876 || arg1 == error_mark_node
9877 || arg2 == error_mark_node)
9880 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9881 op0 = copy_to_mode_reg (tmode, op0);
9883 op2 = copy_to_mode_reg (mode2, op2);
9885 if (op1 == const0_rtx)
9887 addr = gen_rtx_MEM (tmode, op2);
9891 op1 = copy_to_mode_reg (mode1, op1);
9892 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9895 pat = GEN_FCN (icode) (addr, op0);
9902 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9904 tree arg0 = CALL_EXPR_ARG (exp, 0);
9905 tree arg1 = CALL_EXPR_ARG (exp, 1);
9906 tree arg2 = CALL_EXPR_ARG (exp, 2);
9907 rtx op0 = expand_normal (arg0);
9908 rtx op1 = expand_normal (arg1);
9909 rtx op2 = expand_normal (arg2);
9911 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9912 enum machine_mode mode1 = Pmode;
9913 enum machine_mode mode2 = Pmode;
9915 /* Invalid arguments. Bail before doing anything stoopid! */
9916 if (arg0 == error_mark_node
9917 || arg1 == error_mark_node
9918 || arg2 == error_mark_node)
9921 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9922 op0 = copy_to_mode_reg (tmode, op0);
9924 op2 = copy_to_mode_reg (mode2, op2);
9926 if (op1 == const0_rtx)
9928 addr = gen_rtx_MEM (tmode, op2);
9932 op1 = copy_to_mode_reg (mode1, op1);
9933 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9936 pat = GEN_FCN (icode) (addr, op0);
9943 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9946 tree arg0 = CALL_EXPR_ARG (exp, 0);
9947 tree arg1 = CALL_EXPR_ARG (exp, 1);
9948 tree arg2 = CALL_EXPR_ARG (exp, 2);
9949 rtx op0 = expand_normal (arg0);
9950 rtx op1 = expand_normal (arg1);
9951 rtx op2 = expand_normal (arg2);
9952 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9953 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9954 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9955 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9957 if (icode == CODE_FOR_nothing)
9958 /* Builtin not supported on this processor. */
9961 /* If we got invalid arguments bail out before generating bad rtl. */
9962 if (arg0 == error_mark_node
9963 || arg1 == error_mark_node
9964 || arg2 == error_mark_node)
9969 case CODE_FOR_altivec_vsldoi_v4sf:
9970 case CODE_FOR_altivec_vsldoi_v4si:
9971 case CODE_FOR_altivec_vsldoi_v8hi:
9972 case CODE_FOR_altivec_vsldoi_v16qi:
9973 /* Only allow 4-bit unsigned literals. */
9975 if (TREE_CODE (arg2) != INTEGER_CST
9976 || TREE_INT_CST_LOW (arg2) & ~0xf)
9978 error ("argument 3 must be a 4-bit unsigned literal");
9983 case CODE_FOR_vsx_xxpermdi_v2df:
9984 case CODE_FOR_vsx_xxpermdi_v2di:
9985 case CODE_FOR_vsx_xxsldwi_v16qi:
9986 case CODE_FOR_vsx_xxsldwi_v8hi:
9987 case CODE_FOR_vsx_xxsldwi_v4si:
9988 case CODE_FOR_vsx_xxsldwi_v4sf:
9989 case CODE_FOR_vsx_xxsldwi_v2di:
9990 case CODE_FOR_vsx_xxsldwi_v2df:
9991 /* Only allow 2-bit unsigned literals. */
9993 if (TREE_CODE (arg2) != INTEGER_CST
9994 || TREE_INT_CST_LOW (arg2) & ~0x3)
9996 error ("argument 3 must be a 2-bit unsigned literal");
10001 case CODE_FOR_vsx_set_v2df:
10002 case CODE_FOR_vsx_set_v2di:
10003 /* Only allow 1-bit unsigned literals. */
10005 if (TREE_CODE (arg2) != INTEGER_CST
10006 || TREE_INT_CST_LOW (arg2) & ~0x1)
10008 error ("argument 3 must be a 1-bit unsigned literal");
10018 || GET_MODE (target) != tmode
10019 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10020 target = gen_reg_rtx (tmode);
10022 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10023 op0 = copy_to_mode_reg (mode0, op0);
10024 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10025 op1 = copy_to_mode_reg (mode1, op1);
10026 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10027 op2 = copy_to_mode_reg (mode2, op2);
10029 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10030 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10032 pat = GEN_FCN (icode) (target, op0, op1, op2);
10040 /* Expand the lvx builtins. */
10042 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10044 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10045 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10047 enum machine_mode tmode, mode0;
10049 enum insn_code icode;
10053 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10054 icode = CODE_FOR_vector_load_v16qi;
10056 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10057 icode = CODE_FOR_vector_load_v8hi;
10059 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10060 icode = CODE_FOR_vector_load_v4si;
10062 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10063 icode = CODE_FOR_vector_load_v4sf;
10066 *expandedp = false;
10072 arg0 = CALL_EXPR_ARG (exp, 0);
10073 op0 = expand_normal (arg0);
10074 tmode = insn_data[icode].operand[0].mode;
10075 mode0 = insn_data[icode].operand[1].mode;
10078 || GET_MODE (target) != tmode
10079 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10080 target = gen_reg_rtx (tmode);
10082 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10083 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10085 pat = GEN_FCN (icode) (target, op0);
10092 /* Expand the stvx builtins. */
10094 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10097 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10098 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10100 enum machine_mode mode0, mode1;
10102 enum insn_code icode;
10106 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10107 icode = CODE_FOR_vector_store_v16qi;
10109 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10110 icode = CODE_FOR_vector_store_v8hi;
10112 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10113 icode = CODE_FOR_vector_store_v4si;
10115 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10116 icode = CODE_FOR_vector_store_v4sf;
10119 *expandedp = false;
10123 arg0 = CALL_EXPR_ARG (exp, 0);
10124 arg1 = CALL_EXPR_ARG (exp, 1);
10125 op0 = expand_normal (arg0);
10126 op1 = expand_normal (arg1);
10127 mode0 = insn_data[icode].operand[0].mode;
10128 mode1 = insn_data[icode].operand[1].mode;
10130 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10131 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10132 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10133 op1 = copy_to_mode_reg (mode1, op1);
10135 pat = GEN_FCN (icode) (op0, op1);
10143 /* Expand the dst builtins. */
10145 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10148 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10149 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10150 tree arg0, arg1, arg2;
10151 enum machine_mode mode0, mode1;
10152 rtx pat, op0, op1, op2;
10153 const struct builtin_description *d;
10156 *expandedp = false;
10158 /* Handle DST variants. */
10160 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10161 if (d->code == fcode)
10163 arg0 = CALL_EXPR_ARG (exp, 0);
10164 arg1 = CALL_EXPR_ARG (exp, 1);
10165 arg2 = CALL_EXPR_ARG (exp, 2);
10166 op0 = expand_normal (arg0);
10167 op1 = expand_normal (arg1);
10168 op2 = expand_normal (arg2);
10169 mode0 = insn_data[d->icode].operand[0].mode;
10170 mode1 = insn_data[d->icode].operand[1].mode;
10172 /* Invalid arguments, bail out before generating bad rtl. */
10173 if (arg0 == error_mark_node
10174 || arg1 == error_mark_node
10175 || arg2 == error_mark_node)
10180 if (TREE_CODE (arg2) != INTEGER_CST
10181 || TREE_INT_CST_LOW (arg2) & ~0x3)
10183 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10187 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10188 op0 = copy_to_mode_reg (Pmode, op0);
10189 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10190 op1 = copy_to_mode_reg (mode1, op1);
10192 pat = GEN_FCN (d->icode) (op0, op1, op2);
10202 /* Expand vec_init builtin. */
10204 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10206 enum machine_mode tmode = TYPE_MODE (type);
10207 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10208 int i, n_elt = GET_MODE_NUNITS (tmode);
10209 rtvec v = rtvec_alloc (n_elt);
10211 gcc_assert (VECTOR_MODE_P (tmode));
10212 gcc_assert (n_elt == call_expr_nargs (exp));
10214 for (i = 0; i < n_elt; ++i)
10216 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10217 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10220 if (!target || !register_operand (target, tmode))
10221 target = gen_reg_rtx (tmode);
10223 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10227 /* Return the integer constant in ARG. Constrain it to be in the range
10228 of the subparts of VEC_TYPE; issue an error if not. */
10231 get_element_number (tree vec_type, tree arg)
10233 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10235 if (!host_integerp (arg, 1)
10236 || (elt = tree_low_cst (arg, 1), elt > max))
10238 error ("selector must be an integer constant in the range 0..%wi", max);
10245 /* Expand vec_set builtin. */
10247 altivec_expand_vec_set_builtin (tree exp)
10249 enum machine_mode tmode, mode1;
10250 tree arg0, arg1, arg2;
10254 arg0 = CALL_EXPR_ARG (exp, 0);
10255 arg1 = CALL_EXPR_ARG (exp, 1);
10256 arg2 = CALL_EXPR_ARG (exp, 2);
10258 tmode = TYPE_MODE (TREE_TYPE (arg0));
10259 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10260 gcc_assert (VECTOR_MODE_P (tmode));
10262 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10263 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10264 elt = get_element_number (TREE_TYPE (arg0), arg2);
10266 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10267 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10269 op0 = force_reg (tmode, op0);
10270 op1 = force_reg (mode1, op1);
10272 rs6000_expand_vector_set (op0, op1, elt);
10277 /* Expand vec_ext builtin. */
10279 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10281 enum machine_mode tmode, mode0;
10286 arg0 = CALL_EXPR_ARG (exp, 0);
10287 arg1 = CALL_EXPR_ARG (exp, 1);
10289 op0 = expand_normal (arg0);
10290 elt = get_element_number (TREE_TYPE (arg0), arg1);
10292 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10293 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10294 gcc_assert (VECTOR_MODE_P (mode0));
10296 op0 = force_reg (mode0, op0);
10298 if (optimize || !target || !register_operand (target, tmode))
10299 target = gen_reg_rtx (tmode);
10301 rs6000_expand_vector_extract (target, op0, elt);
10306 /* Expand the builtin in EXP and store the result in TARGET. Store
10307 true in *EXPANDEDP if we found a builtin to expand. */
10309 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10311 const struct builtin_description *d;
10312 const struct builtin_description_predicates *dp;
10314 enum insn_code icode;
10315 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10318 enum machine_mode tmode, mode0;
10319 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10321 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10322 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10323 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10324 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10327 error ("unresolved overload for Altivec builtin %qF", fndecl);
10331 target = altivec_expand_ld_builtin (exp, target, expandedp);
10335 target = altivec_expand_st_builtin (exp, target, expandedp);
10339 target = altivec_expand_dst_builtin (exp, target, expandedp);
10347 case ALTIVEC_BUILTIN_STVX:
10348 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10349 case ALTIVEC_BUILTIN_STVEBX:
10350 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10351 case ALTIVEC_BUILTIN_STVEHX:
10352 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10353 case ALTIVEC_BUILTIN_STVEWX:
10354 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10355 case ALTIVEC_BUILTIN_STVXL:
10356 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10358 case ALTIVEC_BUILTIN_STVLX:
10359 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10360 case ALTIVEC_BUILTIN_STVLXL:
10361 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10362 case ALTIVEC_BUILTIN_STVRX:
10363 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10364 case ALTIVEC_BUILTIN_STVRXL:
10365 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10367 case ALTIVEC_BUILTIN_MFVSCR:
10368 icode = CODE_FOR_altivec_mfvscr;
10369 tmode = insn_data[icode].operand[0].mode;
10372 || GET_MODE (target) != tmode
10373 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10374 target = gen_reg_rtx (tmode);
10376 pat = GEN_FCN (icode) (target);
10382 case ALTIVEC_BUILTIN_MTVSCR:
10383 icode = CODE_FOR_altivec_mtvscr;
10384 arg0 = CALL_EXPR_ARG (exp, 0);
10385 op0 = expand_normal (arg0);
10386 mode0 = insn_data[icode].operand[0].mode;
10388 /* If we got invalid arguments bail out before generating bad rtl. */
10389 if (arg0 == error_mark_node)
10392 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10393 op0 = copy_to_mode_reg (mode0, op0);
10395 pat = GEN_FCN (icode) (op0);
10400 case ALTIVEC_BUILTIN_DSSALL:
10401 emit_insn (gen_altivec_dssall ());
10404 case ALTIVEC_BUILTIN_DSS:
10405 icode = CODE_FOR_altivec_dss;
10406 arg0 = CALL_EXPR_ARG (exp, 0);
10408 op0 = expand_normal (arg0);
10409 mode0 = insn_data[icode].operand[0].mode;
10411 /* If we got invalid arguments bail out before generating bad rtl. */
10412 if (arg0 == error_mark_node)
10415 if (TREE_CODE (arg0) != INTEGER_CST
10416 || TREE_INT_CST_LOW (arg0) & ~0x3)
10418 error ("argument to dss must be a 2-bit unsigned literal");
10422 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10423 op0 = copy_to_mode_reg (mode0, op0);
10425 emit_insn (gen_altivec_dss (op0));
10428 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10429 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10430 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10431 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10432 case VSX_BUILTIN_VEC_INIT_V2DF:
10433 case VSX_BUILTIN_VEC_INIT_V2DI:
10434 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10436 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10437 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10438 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10439 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10440 case VSX_BUILTIN_VEC_SET_V2DF:
10441 case VSX_BUILTIN_VEC_SET_V2DI:
10442 return altivec_expand_vec_set_builtin (exp);
10444 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10445 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10446 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10447 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10448 case VSX_BUILTIN_VEC_EXT_V2DF:
10449 case VSX_BUILTIN_VEC_EXT_V2DI:
10450 return altivec_expand_vec_ext_builtin (exp, target);
10454 /* Fall through. */
10457 /* Expand abs* operations. */
10459 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10460 if (d->code == fcode)
10461 return altivec_expand_abs_builtin (d->icode, exp, target);
10463 /* Expand the AltiVec predicates. */
10464 dp = bdesc_altivec_preds;
10465 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10466 if (dp->code == fcode)
10467 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10469 /* LV* are funky. We initialized them differently. */
10472 case ALTIVEC_BUILTIN_LVSL:
10473 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10474 exp, target, false);
10475 case ALTIVEC_BUILTIN_LVSR:
10476 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10477 exp, target, false);
10478 case ALTIVEC_BUILTIN_LVEBX:
10479 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10480 exp, target, false);
10481 case ALTIVEC_BUILTIN_LVEHX:
10482 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10483 exp, target, false);
10484 case ALTIVEC_BUILTIN_LVEWX:
10485 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10486 exp, target, false);
10487 case ALTIVEC_BUILTIN_LVXL:
10488 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10489 exp, target, false);
10490 case ALTIVEC_BUILTIN_LVX:
10491 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10492 exp, target, false);
10493 case ALTIVEC_BUILTIN_LVLX:
10494 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10495 exp, target, true);
10496 case ALTIVEC_BUILTIN_LVLXL:
10497 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10498 exp, target, true);
10499 case ALTIVEC_BUILTIN_LVRX:
10500 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10501 exp, target, true);
10502 case ALTIVEC_BUILTIN_LVRXL:
10503 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10504 exp, target, true);
10507 /* Fall through. */
10510 *expandedp = false;
10514 /* Expand the builtin in EXP and store the result in TARGET. Store
10515 true in *EXPANDEDP if we found a builtin to expand. */
10517 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10519 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10520 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10521 const struct builtin_description *d;
10528 case PAIRED_BUILTIN_STX:
10529 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10530 case PAIRED_BUILTIN_LX:
10531 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10534 /* Fall through. */
10537 /* Expand the paired predicates. */
10538 d = bdesc_paired_preds;
10539 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10540 if (d->code == fcode)
10541 return paired_expand_predicate_builtin (d->icode, exp, target);
10543 *expandedp = false;
10547 /* Binops that need to be initialized manually, but can be expanded
10548 automagically by rs6000_expand_binop_builtin. */
10549 static struct builtin_description bdesc_2arg_spe[] =
10551 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10552 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10553 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10554 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10555 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10556 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10557 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10558 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10559 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10560 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10561 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10562 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10563 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10564 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10565 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10566 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10567 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10568 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10569 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10570 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10571 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10572 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10575 /* Expand the builtin in EXP and store the result in TARGET. Store
10576 true in *EXPANDEDP if we found a builtin to expand.
10578 This expands the SPE builtins that are not simple unary and binary
10581 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10583 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10585 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10586 enum insn_code icode;
10587 enum machine_mode tmode, mode0;
10589 struct builtin_description *d;
10594 /* Syntax check for a 5-bit unsigned immediate. */
10597 case SPE_BUILTIN_EVSTDD:
10598 case SPE_BUILTIN_EVSTDH:
10599 case SPE_BUILTIN_EVSTDW:
10600 case SPE_BUILTIN_EVSTWHE:
10601 case SPE_BUILTIN_EVSTWHO:
10602 case SPE_BUILTIN_EVSTWWE:
10603 case SPE_BUILTIN_EVSTWWO:
10604 arg1 = CALL_EXPR_ARG (exp, 2);
10605 if (TREE_CODE (arg1) != INTEGER_CST
10606 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10608 error ("argument 2 must be a 5-bit unsigned literal");
10616 /* The evsplat*i instructions are not quite generic. */
10619 case SPE_BUILTIN_EVSPLATFI:
10620 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10622 case SPE_BUILTIN_EVSPLATI:
10623 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10629 d = (struct builtin_description *) bdesc_2arg_spe;
10630 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10631 if (d->code == fcode)
10632 return rs6000_expand_binop_builtin (d->icode, exp, target);
10634 d = (struct builtin_description *) bdesc_spe_predicates;
10635 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10636 if (d->code == fcode)
10637 return spe_expand_predicate_builtin (d->icode, exp, target);
10639 d = (struct builtin_description *) bdesc_spe_evsel;
10640 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10641 if (d->code == fcode)
10642 return spe_expand_evsel_builtin (d->icode, exp, target);
10646 case SPE_BUILTIN_EVSTDDX:
10647 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10648 case SPE_BUILTIN_EVSTDHX:
10649 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10650 case SPE_BUILTIN_EVSTDWX:
10651 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10652 case SPE_BUILTIN_EVSTWHEX:
10653 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10654 case SPE_BUILTIN_EVSTWHOX:
10655 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10656 case SPE_BUILTIN_EVSTWWEX:
10657 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10658 case SPE_BUILTIN_EVSTWWOX:
10659 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10660 case SPE_BUILTIN_EVSTDD:
10661 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10662 case SPE_BUILTIN_EVSTDH:
10663 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10664 case SPE_BUILTIN_EVSTDW:
10665 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10666 case SPE_BUILTIN_EVSTWHE:
10667 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10668 case SPE_BUILTIN_EVSTWHO:
10669 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10670 case SPE_BUILTIN_EVSTWWE:
10671 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10672 case SPE_BUILTIN_EVSTWWO:
10673 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10674 case SPE_BUILTIN_MFSPEFSCR:
10675 icode = CODE_FOR_spe_mfspefscr;
10676 tmode = insn_data[icode].operand[0].mode;
10679 || GET_MODE (target) != tmode
10680 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10681 target = gen_reg_rtx (tmode);
10683 pat = GEN_FCN (icode) (target);
10688 case SPE_BUILTIN_MTSPEFSCR:
10689 icode = CODE_FOR_spe_mtspefscr;
10690 arg0 = CALL_EXPR_ARG (exp, 0);
10691 op0 = expand_normal (arg0);
10692 mode0 = insn_data[icode].operand[0].mode;
10694 if (arg0 == error_mark_node)
10697 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10698 op0 = copy_to_mode_reg (mode0, op0);
10700 pat = GEN_FCN (icode) (op0);
10708 *expandedp = false;
10713 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10715 rtx pat, scratch, tmp;
10716 tree form = CALL_EXPR_ARG (exp, 0);
10717 tree arg0 = CALL_EXPR_ARG (exp, 1);
10718 tree arg1 = CALL_EXPR_ARG (exp, 2);
10719 rtx op0 = expand_normal (arg0);
10720 rtx op1 = expand_normal (arg1);
10721 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10722 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10724 enum rtx_code code;
10726 if (TREE_CODE (form) != INTEGER_CST)
10728 error ("argument 1 of __builtin_paired_predicate must be a constant");
10732 form_int = TREE_INT_CST_LOW (form);
10734 gcc_assert (mode0 == mode1);
10736 if (arg0 == error_mark_node || arg1 == error_mark_node)
10740 || GET_MODE (target) != SImode
10741 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10742 target = gen_reg_rtx (SImode);
10743 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10744 op0 = copy_to_mode_reg (mode0, op0);
10745 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10746 op1 = copy_to_mode_reg (mode1, op1);
10748 scratch = gen_reg_rtx (CCFPmode);
10750 pat = GEN_FCN (icode) (scratch, op0, op1);
10772 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10775 error ("argument 1 of __builtin_paired_predicate is out of range");
10779 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10780 emit_move_insn (target, tmp);
10785 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10787 rtx pat, scratch, tmp;
10788 tree form = CALL_EXPR_ARG (exp, 0);
10789 tree arg0 = CALL_EXPR_ARG (exp, 1);
10790 tree arg1 = CALL_EXPR_ARG (exp, 2);
10791 rtx op0 = expand_normal (arg0);
10792 rtx op1 = expand_normal (arg1);
10793 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10794 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10796 enum rtx_code code;
10798 if (TREE_CODE (form) != INTEGER_CST)
10800 error ("argument 1 of __builtin_spe_predicate must be a constant");
10804 form_int = TREE_INT_CST_LOW (form);
10806 gcc_assert (mode0 == mode1);
10808 if (arg0 == error_mark_node || arg1 == error_mark_node)
10812 || GET_MODE (target) != SImode
10813 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10814 target = gen_reg_rtx (SImode);
10816 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10817 op0 = copy_to_mode_reg (mode0, op0);
10818 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10819 op1 = copy_to_mode_reg (mode1, op1);
10821 scratch = gen_reg_rtx (CCmode);
10823 pat = GEN_FCN (icode) (scratch, op0, op1);
10828 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10829 _lower_. We use one compare, but look in different bits of the
10830 CR for each variant.
10832 There are 2 elements in each SPE simd type (upper/lower). The CR
10833 bits are set as follows:
10835 BIT0 | BIT 1 | BIT 2 | BIT 3
10836 U | L | (U | L) | (U & L)
10838 So, for an "all" relationship, BIT 3 would be set.
10839 For an "any" relationship, BIT 2 would be set. Etc.
10841 Following traditional nomenclature, these bits map to:
10843 BIT0 | BIT 1 | BIT 2 | BIT 3
10846 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10851 /* All variant. OV bit. */
10853 /* We need to get to the OV bit, which is the ORDERED bit. We
10854 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10855 that's ugly and will make validate_condition_mode die.
10856 So let's just use another pattern. */
10857 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10859 /* Any variant. EQ bit. */
10863 /* Upper variant. LT bit. */
10867 /* Lower variant. GT bit. */
10872 error ("argument 1 of __builtin_spe_predicate is out of range");
10876 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10877 emit_move_insn (target, tmp);
10882 /* The evsel builtins look like this:
10884 e = __builtin_spe_evsel_OP (a, b, c, d);
10886 and work like this:
10888 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10889 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10893 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10896 tree arg0 = CALL_EXPR_ARG (exp, 0);
10897 tree arg1 = CALL_EXPR_ARG (exp, 1);
10898 tree arg2 = CALL_EXPR_ARG (exp, 2);
10899 tree arg3 = CALL_EXPR_ARG (exp, 3);
10900 rtx op0 = expand_normal (arg0);
10901 rtx op1 = expand_normal (arg1);
10902 rtx op2 = expand_normal (arg2);
10903 rtx op3 = expand_normal (arg3);
10904 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10905 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10907 gcc_assert (mode0 == mode1);
10909 if (arg0 == error_mark_node || arg1 == error_mark_node
10910 || arg2 == error_mark_node || arg3 == error_mark_node)
10914 || GET_MODE (target) != mode0
10915 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10916 target = gen_reg_rtx (mode0);
10918 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10919 op0 = copy_to_mode_reg (mode0, op0);
10920 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10921 op1 = copy_to_mode_reg (mode0, op1);
10922 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10923 op2 = copy_to_mode_reg (mode0, op2);
10924 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10925 op3 = copy_to_mode_reg (mode0, op3);
10927 /* Generate the compare. */
10928 scratch = gen_reg_rtx (CCmode);
10929 pat = GEN_FCN (icode) (scratch, op0, op1);
10934 if (mode0 == V2SImode)
10935 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10937 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10942 /* Expand an expression EXP that calls a built-in function,
10943 with result going to TARGET if that's convenient
10944 (and in mode MODE if that's convenient).
10945 SUBTARGET may be used as the target for computing one of EXP's operands.
10946 IGNORE is nonzero if the value is to be ignored. */
10949 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10950 enum machine_mode mode ATTRIBUTE_UNUSED,
10951 int ignore ATTRIBUTE_UNUSED)
10953 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10954 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10955 const struct builtin_description *d;
10960 if (fcode == RS6000_BUILTIN_RECIP)
10961 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10963 if (fcode == RS6000_BUILTIN_RECIPF)
10964 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10966 if (fcode == RS6000_BUILTIN_RSQRTF)
10967 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10969 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10970 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10972 if (fcode == POWER7_BUILTIN_BPERMD)
10973 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10974 ? CODE_FOR_bpermd_di
10975 : CODE_FOR_bpermd_si), exp, target);
10977 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10978 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10980 int icode = (int) CODE_FOR_altivec_lvsr;
10981 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10982 enum machine_mode mode = insn_data[icode].operand[1].mode;
10986 gcc_assert (TARGET_ALTIVEC);
10988 arg = CALL_EXPR_ARG (exp, 0);
10989 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10990 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10991 addr = memory_address (mode, op);
10992 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10996 /* For the load case need to negate the address. */
10997 op = gen_reg_rtx (GET_MODE (addr));
10998 emit_insn (gen_rtx_SET (VOIDmode, op,
10999 gen_rtx_NEG (GET_MODE (addr), addr)));
11001 op = gen_rtx_MEM (mode, op);
11004 || GET_MODE (target) != tmode
11005 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11006 target = gen_reg_rtx (tmode);
11008 /*pat = gen_altivec_lvsr (target, op);*/
11009 pat = GEN_FCN (icode) (target, op);
11017 /* FIXME: There's got to be a nicer way to handle this case than
11018 constructing a new CALL_EXPR. */
11019 if (fcode == ALTIVEC_BUILTIN_VCFUX
11020 || fcode == ALTIVEC_BUILTIN_VCFSX
11021 || fcode == ALTIVEC_BUILTIN_VCTUXS
11022 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11024 if (call_expr_nargs (exp) == 1)
11025 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11026 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11029 if (TARGET_ALTIVEC)
11031 ret = altivec_expand_builtin (exp, target, &success);
11038 ret = spe_expand_builtin (exp, target, &success);
11043 if (TARGET_PAIRED_FLOAT)
11045 ret = paired_expand_builtin (exp, target, &success);
11051 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11053 /* Handle simple unary operations. */
11054 d = (struct builtin_description *) bdesc_1arg;
11055 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11056 if (d->code == fcode)
11057 return rs6000_expand_unop_builtin (d->icode, exp, target);
11059 /* Handle simple binary operations. */
11060 d = (struct builtin_description *) bdesc_2arg;
11061 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11062 if (d->code == fcode)
11063 return rs6000_expand_binop_builtin (d->icode, exp, target);
11065 /* Handle simple ternary operations. */
11067 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11068 if (d->code == fcode)
11069 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11071 gcc_unreachable ();
11075 rs6000_init_builtins (void)
11079 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11080 V2SF_type_node = build_vector_type (float_type_node, 2);
11081 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11082 V2DF_type_node = build_vector_type (double_type_node, 2);
11083 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11084 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11085 V4SF_type_node = build_vector_type (float_type_node, 4);
11086 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11087 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11089 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11090 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11091 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11092 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11094 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11095 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11096 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11097 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11099 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11100 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11101 'vector unsigned short'. */
11103 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11104 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11105 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11106 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11107 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11109 long_integer_type_internal_node = long_integer_type_node;
11110 long_unsigned_type_internal_node = long_unsigned_type_node;
11111 intQI_type_internal_node = intQI_type_node;
11112 uintQI_type_internal_node = unsigned_intQI_type_node;
11113 intHI_type_internal_node = intHI_type_node;
11114 uintHI_type_internal_node = unsigned_intHI_type_node;
11115 intSI_type_internal_node = intSI_type_node;
11116 uintSI_type_internal_node = unsigned_intSI_type_node;
11117 intDI_type_internal_node = intDI_type_node;
11118 uintDI_type_internal_node = unsigned_intDI_type_node;
11119 float_type_internal_node = float_type_node;
11120 double_type_internal_node = float_type_node;
11121 void_type_internal_node = void_type_node;
11123 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11125 builtin_mode_to_type[QImode][0] = integer_type_node;
11126 builtin_mode_to_type[HImode][0] = integer_type_node;
11127 builtin_mode_to_type[SImode][0] = intSI_type_node;
11128 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11129 builtin_mode_to_type[DImode][0] = intDI_type_node;
11130 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11131 builtin_mode_to_type[SFmode][0] = float_type_node;
11132 builtin_mode_to_type[DFmode][0] = double_type_node;
11133 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11134 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11135 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11136 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11137 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11138 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11139 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11140 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11141 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11142 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11143 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11144 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11145 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11147 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11148 get_identifier ("__bool char"),
11149 bool_char_type_node);
11150 TYPE_NAME (bool_char_type_node) = tdecl;
11151 (*lang_hooks.decls.pushdecl) (tdecl);
11152 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11153 get_identifier ("__bool short"),
11154 bool_short_type_node);
11155 TYPE_NAME (bool_short_type_node) = tdecl;
11156 (*lang_hooks.decls.pushdecl) (tdecl);
11157 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11158 get_identifier ("__bool int"),
11159 bool_int_type_node);
11160 TYPE_NAME (bool_int_type_node) = tdecl;
11161 (*lang_hooks.decls.pushdecl) (tdecl);
11162 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11164 TYPE_NAME (pixel_type_node) = tdecl;
11165 (*lang_hooks.decls.pushdecl) (tdecl);
11167 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11168 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11169 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11170 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11171 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11173 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11174 get_identifier ("__vector unsigned char"),
11175 unsigned_V16QI_type_node);
11176 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11177 (*lang_hooks.decls.pushdecl) (tdecl);
11178 tdecl = build_decl (BUILTINS_LOCATION,
11179 TYPE_DECL, get_identifier ("__vector signed char"),
11181 TYPE_NAME (V16QI_type_node) = tdecl;
11182 (*lang_hooks.decls.pushdecl) (tdecl);
11183 tdecl = build_decl (BUILTINS_LOCATION,
11184 TYPE_DECL, get_identifier ("__vector __bool char"),
11185 bool_V16QI_type_node);
11186 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11187 (*lang_hooks.decls.pushdecl) (tdecl);
11189 tdecl = build_decl (BUILTINS_LOCATION,
11190 TYPE_DECL, get_identifier ("__vector unsigned short"),
11191 unsigned_V8HI_type_node);
11192 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11193 (*lang_hooks.decls.pushdecl) (tdecl);
11194 tdecl = build_decl (BUILTINS_LOCATION,
11195 TYPE_DECL, get_identifier ("__vector signed short"),
11197 TYPE_NAME (V8HI_type_node) = tdecl;
11198 (*lang_hooks.decls.pushdecl) (tdecl);
11199 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11200 get_identifier ("__vector __bool short"),
11201 bool_V8HI_type_node);
11202 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11203 (*lang_hooks.decls.pushdecl) (tdecl);
11205 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11206 get_identifier ("__vector unsigned int"),
11207 unsigned_V4SI_type_node);
11208 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11209 (*lang_hooks.decls.pushdecl) (tdecl);
11210 tdecl = build_decl (BUILTINS_LOCATION,
11211 TYPE_DECL, get_identifier ("__vector signed int"),
11213 TYPE_NAME (V4SI_type_node) = tdecl;
11214 (*lang_hooks.decls.pushdecl) (tdecl);
11215 tdecl = build_decl (BUILTINS_LOCATION,
11216 TYPE_DECL, get_identifier ("__vector __bool int"),
11217 bool_V4SI_type_node);
11218 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11219 (*lang_hooks.decls.pushdecl) (tdecl);
11221 tdecl = build_decl (BUILTINS_LOCATION,
11222 TYPE_DECL, get_identifier ("__vector float"),
11224 TYPE_NAME (V4SF_type_node) = tdecl;
11225 (*lang_hooks.decls.pushdecl) (tdecl);
11226 tdecl = build_decl (BUILTINS_LOCATION,
11227 TYPE_DECL, get_identifier ("__vector __pixel"),
11228 pixel_V8HI_type_node);
11229 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11230 (*lang_hooks.decls.pushdecl) (tdecl);
11234 tdecl = build_decl (BUILTINS_LOCATION,
11235 TYPE_DECL, get_identifier ("__vector double"),
11237 TYPE_NAME (V2DF_type_node) = tdecl;
11238 (*lang_hooks.decls.pushdecl) (tdecl);
11240 tdecl = build_decl (BUILTINS_LOCATION,
11241 TYPE_DECL, get_identifier ("__vector long"),
11243 TYPE_NAME (V2DI_type_node) = tdecl;
11244 (*lang_hooks.decls.pushdecl) (tdecl);
11246 tdecl = build_decl (BUILTINS_LOCATION,
11247 TYPE_DECL, get_identifier ("__vector unsigned long"),
11248 unsigned_V2DI_type_node);
11249 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11250 (*lang_hooks.decls.pushdecl) (tdecl);
11252 tdecl = build_decl (BUILTINS_LOCATION,
11253 TYPE_DECL, get_identifier ("__vector __bool long"),
11254 bool_V2DI_type_node);
11255 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11256 (*lang_hooks.decls.pushdecl) (tdecl);
11259 if (TARGET_PAIRED_FLOAT)
11260 paired_init_builtins ();
11262 spe_init_builtins ();
11263 if (TARGET_ALTIVEC)
11264 altivec_init_builtins ();
11265 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11266 rs6000_common_init_builtins ();
11267 if (TARGET_PPC_GFXOPT)
11269 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11270 RS6000_BUILTIN_RECIPF,
11271 "__builtin_recipdivf");
11272 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11273 RS6000_BUILTIN_RECIPF);
11275 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11276 RS6000_BUILTIN_RSQRTF,
11277 "__builtin_rsqrtf");
11278 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11279 RS6000_BUILTIN_RSQRTF);
11281 if (TARGET_POPCNTB)
11283 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11284 RS6000_BUILTIN_RECIP,
11285 "__builtin_recipdiv");
11286 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11287 RS6000_BUILTIN_RECIP);
11290 if (TARGET_POPCNTD)
11292 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11293 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11294 POWER7_BUILTIN_BPERMD,
11295 "__builtin_bpermd");
11296 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11297 POWER7_BUILTIN_BPERMD);
11299 if (TARGET_POWERPC)
11301 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11302 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11303 unsigned_intHI_type_node,
11305 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11306 RS6000_BUILTIN_BSWAP_HI);
11310 /* AIX libm provides clog as __clog. */
11311 if (built_in_decls [BUILT_IN_CLOG])
11312 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11315 #ifdef SUBTARGET_INIT_BUILTINS
11316 SUBTARGET_INIT_BUILTINS;
11320 /* Returns the rs6000 builtin decl for CODE. */
11323 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11325 if (code >= RS6000_BUILTIN_COUNT)
11326 return error_mark_node;
11328 return rs6000_builtin_decls[code];
11331 /* Search through a set of builtins and enable the mask bits.
11332 DESC is an array of builtins.
11333 SIZE is the total number of builtins.
11334 START is the builtin enum at which to start.
11335 END is the builtin enum at which to end. */
11337 enable_mask_for_builtins (struct builtin_description *desc, int size,
11338 enum rs6000_builtins start,
11339 enum rs6000_builtins end)
11343 for (i = 0; i < size; ++i)
11344 if (desc[i].code == start)
11350 for (; i < size; ++i)
11352 /* Flip all the bits on. */
11353 desc[i].mask = target_flags;
11354 if (desc[i].code == end)
11360 spe_init_builtins (void)
11362 tree endlink = void_list_node;
11363 tree puint_type_node = build_pointer_type (unsigned_type_node);
11364 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11365 struct builtin_description *d;
11368 tree v2si_ftype_4_v2si
11369 = build_function_type
11370 (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,
11374 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11377 tree v2sf_ftype_4_v2sf
11378 = build_function_type
11379 (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,
11383 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11386 tree int_ftype_int_v2si_v2si
11387 = build_function_type
11388 (integer_type_node,
11389 tree_cons (NULL_TREE, integer_type_node,
11390 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11391 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11394 tree int_ftype_int_v2sf_v2sf
11395 = build_function_type
11396 (integer_type_node,
11397 tree_cons (NULL_TREE, integer_type_node,
11398 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11399 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11402 tree void_ftype_v2si_puint_int
11403 = build_function_type (void_type_node,
11404 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11405 tree_cons (NULL_TREE, puint_type_node,
11406 tree_cons (NULL_TREE,
11410 tree void_ftype_v2si_puint_char
11411 = build_function_type (void_type_node,
11412 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11413 tree_cons (NULL_TREE, puint_type_node,
11414 tree_cons (NULL_TREE,
11418 tree void_ftype_v2si_pv2si_int
11419 = build_function_type (void_type_node,
11420 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11421 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11422 tree_cons (NULL_TREE,
11426 tree void_ftype_v2si_pv2si_char
11427 = build_function_type (void_type_node,
11428 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11429 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11430 tree_cons (NULL_TREE,
11434 tree void_ftype_int
11435 = build_function_type (void_type_node,
11436 tree_cons (NULL_TREE, integer_type_node, endlink));
11438 tree int_ftype_void
11439 = build_function_type (integer_type_node, endlink);
11441 tree v2si_ftype_pv2si_int
11442 = build_function_type (opaque_V2SI_type_node,
11443 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11444 tree_cons (NULL_TREE, integer_type_node,
11447 tree v2si_ftype_puint_int
11448 = build_function_type (opaque_V2SI_type_node,
11449 tree_cons (NULL_TREE, puint_type_node,
11450 tree_cons (NULL_TREE, integer_type_node,
11453 tree v2si_ftype_pushort_int
11454 = build_function_type (opaque_V2SI_type_node,
11455 tree_cons (NULL_TREE, pushort_type_node,
11456 tree_cons (NULL_TREE, integer_type_node,
11459 tree v2si_ftype_signed_char
11460 = build_function_type (opaque_V2SI_type_node,
11461 tree_cons (NULL_TREE, signed_char_type_node,
11464 /* The initialization of the simple binary and unary builtins is
11465 done in rs6000_common_init_builtins, but we have to enable the
11466 mask bits here manually because we have run out of `target_flags'
11467 bits. We really need to redesign this mask business. */
11469 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11470 ARRAY_SIZE (bdesc_2arg),
11471 SPE_BUILTIN_EVADDW,
11472 SPE_BUILTIN_EVXOR);
11473 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11474 ARRAY_SIZE (bdesc_1arg),
11476 SPE_BUILTIN_EVSUBFUSIAAW);
11477 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11478 ARRAY_SIZE (bdesc_spe_predicates),
11479 SPE_BUILTIN_EVCMPEQ,
11480 SPE_BUILTIN_EVFSTSTLT);
11481 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11482 ARRAY_SIZE (bdesc_spe_evsel),
11483 SPE_BUILTIN_EVSEL_CMPGTS,
11484 SPE_BUILTIN_EVSEL_FSTSTEQ);
11486 (*lang_hooks.decls.pushdecl)
11487 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11488 get_identifier ("__ev64_opaque__"),
11489 opaque_V2SI_type_node));
11491 /* Initialize irregular SPE builtins. */
11493 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11494 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11495 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11496 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11497 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11498 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11499 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11500 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11501 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11502 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11503 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11504 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11505 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11506 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11507 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11508 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11509 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11510 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11513 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11514 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11515 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11516 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11517 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11518 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11519 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11520 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11521 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11522 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11523 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11524 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11525 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11526 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11527 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11528 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11529 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11530 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11531 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11532 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11533 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11534 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11537 d = (struct builtin_description *) bdesc_spe_predicates;
11538 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11542 switch (insn_data[d->icode].operand[1].mode)
11545 type = int_ftype_int_v2si_v2si;
11548 type = int_ftype_int_v2sf_v2sf;
11551 gcc_unreachable ();
11554 def_builtin (d->mask, d->name, type, d->code);
11557 /* Evsel predicates. */
11558 d = (struct builtin_description *) bdesc_spe_evsel;
11559 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11563 switch (insn_data[d->icode].operand[1].mode)
11566 type = v2si_ftype_4_v2si;
11569 type = v2sf_ftype_4_v2sf;
11572 gcc_unreachable ();
11575 def_builtin (d->mask, d->name, type, d->code);
11580 paired_init_builtins (void)
11582 const struct builtin_description *d;
11584 tree endlink = void_list_node;
11586 tree int_ftype_int_v2sf_v2sf
11587 = build_function_type
11588 (integer_type_node,
11589 tree_cons (NULL_TREE, integer_type_node,
11590 tree_cons (NULL_TREE, V2SF_type_node,
11591 tree_cons (NULL_TREE, V2SF_type_node,
11593 tree pcfloat_type_node =
11594 build_pointer_type (build_qualified_type
11595 (float_type_node, TYPE_QUAL_CONST));
11597 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11598 long_integer_type_node,
11601 tree void_ftype_v2sf_long_pcfloat =
11602 build_function_type_list (void_type_node,
11604 long_integer_type_node,
11609 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11610 PAIRED_BUILTIN_LX);
11613 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11614 PAIRED_BUILTIN_STX);
11617 d = bdesc_paired_preds;
11618 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11622 switch (insn_data[d->icode].operand[1].mode)
11625 type = int_ftype_int_v2sf_v2sf;
11628 gcc_unreachable ();
11631 def_builtin (d->mask, d->name, type, d->code);
11636 altivec_init_builtins (void)
11638 const struct builtin_description *d;
11639 const struct builtin_description_predicates *dp;
11643 tree pfloat_type_node = build_pointer_type (float_type_node);
11644 tree pint_type_node = build_pointer_type (integer_type_node);
11645 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11646 tree pchar_type_node = build_pointer_type (char_type_node);
11648 tree pvoid_type_node = build_pointer_type (void_type_node);
11650 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11651 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11652 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11653 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11655 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11657 tree int_ftype_opaque
11658 = build_function_type_list (integer_type_node,
11659 opaque_V4SI_type_node, NULL_TREE);
11660 tree opaque_ftype_opaque
11661 = build_function_type (integer_type_node,
11663 tree opaque_ftype_opaque_int
11664 = build_function_type_list (opaque_V4SI_type_node,
11665 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11666 tree opaque_ftype_opaque_opaque_int
11667 = build_function_type_list (opaque_V4SI_type_node,
11668 opaque_V4SI_type_node, opaque_V4SI_type_node,
11669 integer_type_node, NULL_TREE);
11670 tree int_ftype_int_opaque_opaque
11671 = build_function_type_list (integer_type_node,
11672 integer_type_node, opaque_V4SI_type_node,
11673 opaque_V4SI_type_node, NULL_TREE);
11674 tree int_ftype_int_v4si_v4si
11675 = build_function_type_list (integer_type_node,
11676 integer_type_node, V4SI_type_node,
11677 V4SI_type_node, NULL_TREE);
11678 tree v4sf_ftype_pcfloat
11679 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11680 tree void_ftype_pfloat_v4sf
11681 = build_function_type_list (void_type_node,
11682 pfloat_type_node, V4SF_type_node, NULL_TREE);
11683 tree v4si_ftype_pcint
11684 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11685 tree void_ftype_pint_v4si
11686 = build_function_type_list (void_type_node,
11687 pint_type_node, V4SI_type_node, NULL_TREE);
11688 tree v8hi_ftype_pcshort
11689 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11690 tree void_ftype_pshort_v8hi
11691 = build_function_type_list (void_type_node,
11692 pshort_type_node, V8HI_type_node, NULL_TREE);
11693 tree v16qi_ftype_pcchar
11694 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11695 tree void_ftype_pchar_v16qi
11696 = build_function_type_list (void_type_node,
11697 pchar_type_node, V16QI_type_node, NULL_TREE);
11698 tree void_ftype_v4si
11699 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11700 tree v8hi_ftype_void
11701 = build_function_type (V8HI_type_node, void_list_node);
11702 tree void_ftype_void
11703 = build_function_type (void_type_node, void_list_node);
11704 tree void_ftype_int
11705 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11707 tree opaque_ftype_long_pcvoid
11708 = build_function_type_list (opaque_V4SI_type_node,
11709 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11710 tree v16qi_ftype_long_pcvoid
11711 = build_function_type_list (V16QI_type_node,
11712 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11713 tree v8hi_ftype_long_pcvoid
11714 = build_function_type_list (V8HI_type_node,
11715 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11716 tree v4si_ftype_long_pcvoid
11717 = build_function_type_list (V4SI_type_node,
11718 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11720 tree void_ftype_opaque_long_pvoid
11721 = build_function_type_list (void_type_node,
11722 opaque_V4SI_type_node, long_integer_type_node,
11723 pvoid_type_node, NULL_TREE);
11724 tree void_ftype_v4si_long_pvoid
11725 = build_function_type_list (void_type_node,
11726 V4SI_type_node, long_integer_type_node,
11727 pvoid_type_node, NULL_TREE);
11728 tree void_ftype_v16qi_long_pvoid
11729 = build_function_type_list (void_type_node,
11730 V16QI_type_node, long_integer_type_node,
11731 pvoid_type_node, NULL_TREE);
11732 tree void_ftype_v8hi_long_pvoid
11733 = build_function_type_list (void_type_node,
11734 V8HI_type_node, long_integer_type_node,
11735 pvoid_type_node, NULL_TREE);
11736 tree int_ftype_int_v8hi_v8hi
11737 = build_function_type_list (integer_type_node,
11738 integer_type_node, V8HI_type_node,
11739 V8HI_type_node, NULL_TREE);
11740 tree int_ftype_int_v16qi_v16qi
11741 = build_function_type_list (integer_type_node,
11742 integer_type_node, V16QI_type_node,
11743 V16QI_type_node, NULL_TREE);
11744 tree int_ftype_int_v4sf_v4sf
11745 = build_function_type_list (integer_type_node,
11746 integer_type_node, V4SF_type_node,
11747 V4SF_type_node, NULL_TREE);
11748 tree int_ftype_int_v2df_v2df
11749 = build_function_type_list (integer_type_node,
11750 integer_type_node, V2DF_type_node,
11751 V2DF_type_node, NULL_TREE);
11752 tree v4si_ftype_v4si
11753 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11754 tree v8hi_ftype_v8hi
11755 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11756 tree v16qi_ftype_v16qi
11757 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11758 tree v4sf_ftype_v4sf
11759 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11760 tree v2df_ftype_v2df
11761 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11762 tree void_ftype_pcvoid_int_int
11763 = build_function_type_list (void_type_node,
11764 pcvoid_type_node, integer_type_node,
11765 integer_type_node, NULL_TREE);
11767 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11768 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11769 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11770 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11771 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11772 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11773 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11774 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11775 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11776 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11777 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11778 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11779 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11780 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11781 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11782 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11783 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11785 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11787 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11799 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11800 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11801 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11802 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11804 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11805 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11807 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11808 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11810 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11811 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11812 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11814 if (rs6000_cpu == PROCESSOR_CELL)
11816 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11817 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11818 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11819 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11824 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11826 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11827 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11828 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11829 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11831 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11832 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11833 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11834 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11836 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11838 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11840 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11841 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11842 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11843 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11844 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11845 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11850 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11851 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11853 /* Add the DST variants. */
11855 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11856 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11858 /* Initialize the predicates. */
11859 dp = bdesc_altivec_preds;
11860 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11862 enum machine_mode mode1;
11864 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11865 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11866 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11867 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11872 mode1 = insn_data[dp->icode].operand[1].mode;
11877 type = int_ftype_int_opaque_opaque;
11880 type = int_ftype_int_v4si_v4si;
11883 type = int_ftype_int_v8hi_v8hi;
11886 type = int_ftype_int_v16qi_v16qi;
11889 type = int_ftype_int_v4sf_v4sf;
11892 type = int_ftype_int_v2df_v2df;
11895 gcc_unreachable ();
11898 def_builtin (dp->mask, dp->name, type, dp->code);
11901 /* Initialize the abs* operators. */
11903 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11905 enum machine_mode mode0;
11908 mode0 = insn_data[d->icode].operand[0].mode;
11913 type = v4si_ftype_v4si;
11916 type = v8hi_ftype_v8hi;
11919 type = v16qi_ftype_v16qi;
11922 type = v4sf_ftype_v4sf;
11925 type = v2df_ftype_v2df;
11928 gcc_unreachable ();
11931 def_builtin (d->mask, d->name, type, d->code);
11934 if (TARGET_ALTIVEC)
11938 /* Initialize target builtin that implements
11939 targetm.vectorize.builtin_mask_for_load. */
11941 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11942 v16qi_ftype_long_pcvoid,
11943 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11944 BUILT_IN_MD, NULL, NULL_TREE);
11945 TREE_READONLY (decl) = 1;
11946 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11947 altivec_builtin_mask_for_load = decl;
11950 /* Access to the vec_init patterns. */
11951 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11952 integer_type_node, integer_type_node,
11953 integer_type_node, NULL_TREE);
11954 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11955 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11957 ftype = build_function_type_list (V8HI_type_node, 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,
11964 short_integer_type_node, NULL_TREE);
11965 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11966 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11968 ftype = build_function_type_list (V16QI_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, char_type_node,
11976 char_type_node, NULL_TREE);
11977 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11978 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11980 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11981 float_type_node, float_type_node,
11982 float_type_node, NULL_TREE);
11983 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11984 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11988 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11989 double_type_node, NULL_TREE);
11990 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11991 VSX_BUILTIN_VEC_INIT_V2DF);
11993 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11994 intDI_type_node, NULL_TREE);
11995 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11996 VSX_BUILTIN_VEC_INIT_V2DI);
11999 /* Access to the vec_set patterns. */
12000 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12002 integer_type_node, NULL_TREE);
12003 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12004 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12006 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12008 integer_type_node, NULL_TREE);
12009 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12010 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12012 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12014 integer_type_node, NULL_TREE);
12015 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12016 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12018 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12020 integer_type_node, NULL_TREE);
12021 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12022 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12026 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12028 integer_type_node, NULL_TREE);
12029 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12030 VSX_BUILTIN_VEC_SET_V2DF);
12032 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12034 integer_type_node, NULL_TREE);
12035 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12036 VSX_BUILTIN_VEC_SET_V2DI);
12039 /* Access to the vec_extract patterns. */
12040 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12041 integer_type_node, NULL_TREE);
12042 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12043 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12045 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12046 integer_type_node, NULL_TREE);
12047 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12048 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12050 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12051 integer_type_node, NULL_TREE);
12052 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12053 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12055 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12056 integer_type_node, NULL_TREE);
12057 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12058 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12062 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12063 integer_type_node, NULL_TREE);
12064 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12065 VSX_BUILTIN_VEC_EXT_V2DF);
12067 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12068 integer_type_node, NULL_TREE);
12069 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12070 VSX_BUILTIN_VEC_EXT_V2DI);
12074 /* Hash function for builtin functions with up to 3 arguments and a return
12077 builtin_hash_function (const void *hash_entry)
12081 const struct builtin_hash_struct *bh =
12082 (const struct builtin_hash_struct *) hash_entry;
12084 for (i = 0; i < 4; i++)
12086 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12087 ret = (ret * 2) + bh->uns_p[i];
12093 /* Compare builtin hash entries H1 and H2 for equivalence. */
12095 builtin_hash_eq (const void *h1, const void *h2)
12097 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12098 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12100 return ((p1->mode[0] == p2->mode[0])
12101 && (p1->mode[1] == p2->mode[1])
12102 && (p1->mode[2] == p2->mode[2])
12103 && (p1->mode[3] == p2->mode[3])
12104 && (p1->uns_p[0] == p2->uns_p[0])
12105 && (p1->uns_p[1] == p2->uns_p[1])
12106 && (p1->uns_p[2] == p2->uns_p[2])
12107 && (p1->uns_p[3] == p2->uns_p[3]));
12110 /* Map types for builtin functions with an explicit return type and up to 3
12111 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12112 of the argument. */
12114 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12115 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12116 enum rs6000_builtins builtin, const char *name)
12118 struct builtin_hash_struct h;
12119 struct builtin_hash_struct *h2;
12123 tree ret_type = NULL_TREE;
12124 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12127 /* Create builtin_hash_table. */
12128 if (builtin_hash_table == NULL)
12129 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12130 builtin_hash_eq, NULL);
12132 h.type = NULL_TREE;
12133 h.mode[0] = mode_ret;
12134 h.mode[1] = mode_arg0;
12135 h.mode[2] = mode_arg1;
12136 h.mode[3] = mode_arg2;
12142 /* If the builtin is a type that produces unsigned results or takes unsigned
12143 arguments, and it is returned as a decl for the vectorizer (such as
12144 widening multiplies, permute), make sure the arguments and return value
12145 are type correct. */
12148 /* unsigned 2 argument functions. */
12149 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12150 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12151 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12152 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12158 /* unsigned 3 argument functions. */
12159 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12160 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12161 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12162 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12163 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12164 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12165 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12166 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12167 case VSX_BUILTIN_VPERM_16QI_UNS:
12168 case VSX_BUILTIN_VPERM_8HI_UNS:
12169 case VSX_BUILTIN_VPERM_4SI_UNS:
12170 case VSX_BUILTIN_VPERM_2DI_UNS:
12171 case VSX_BUILTIN_XXSEL_16QI_UNS:
12172 case VSX_BUILTIN_XXSEL_8HI_UNS:
12173 case VSX_BUILTIN_XXSEL_4SI_UNS:
12174 case VSX_BUILTIN_XXSEL_2DI_UNS:
12181 /* signed permute functions with unsigned char mask. */
12182 case ALTIVEC_BUILTIN_VPERM_16QI:
12183 case ALTIVEC_BUILTIN_VPERM_8HI:
12184 case ALTIVEC_BUILTIN_VPERM_4SI:
12185 case ALTIVEC_BUILTIN_VPERM_4SF:
12186 case ALTIVEC_BUILTIN_VPERM_2DI:
12187 case ALTIVEC_BUILTIN_VPERM_2DF:
12188 case VSX_BUILTIN_VPERM_16QI:
12189 case VSX_BUILTIN_VPERM_8HI:
12190 case VSX_BUILTIN_VPERM_4SI:
12191 case VSX_BUILTIN_VPERM_4SF:
12192 case VSX_BUILTIN_VPERM_2DI:
12193 case VSX_BUILTIN_VPERM_2DF:
12197 /* unsigned args, signed return. */
12198 case VSX_BUILTIN_XVCVUXDDP_UNS:
12199 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12203 /* signed args, unsigned return. */
12204 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12205 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12213 /* Figure out how many args are present. */
12214 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12218 fatal_error ("internal error: builtin function %s had no type", name);
12220 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12221 if (!ret_type && h.uns_p[0])
12222 ret_type = builtin_mode_to_type[h.mode[0]][0];
12225 fatal_error ("internal error: builtin function %s had an unexpected "
12226 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12228 for (i = 0; i < num_args; i++)
12230 int m = (int) h.mode[i+1];
12231 int uns_p = h.uns_p[i+1];
12233 arg_type[i] = builtin_mode_to_type[m][uns_p];
12234 if (!arg_type[i] && uns_p)
12235 arg_type[i] = builtin_mode_to_type[m][0];
12238 fatal_error ("internal error: builtin function %s, argument %d "
12239 "had unexpected argument type %s", name, i,
12240 GET_MODE_NAME (m));
12243 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12244 if (*found == NULL)
12246 h2 = GGC_NEW (struct builtin_hash_struct);
12248 *found = (void *)h2;
12249 args = void_list_node;
12251 for (i = num_args - 1; i >= 0; i--)
12252 args = tree_cons (NULL_TREE, arg_type[i], args);
12254 h2->type = build_function_type (ret_type, args);
12257 return ((struct builtin_hash_struct *)(*found))->type;
12261 rs6000_common_init_builtins (void)
12263 const struct builtin_description *d;
12266 tree opaque_ftype_opaque = NULL_TREE;
12267 tree opaque_ftype_opaque_opaque = NULL_TREE;
12268 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12269 tree v2si_ftype_qi = NULL_TREE;
12270 tree v2si_ftype_v2si_qi = NULL_TREE;
12271 tree v2si_ftype_int_qi = NULL_TREE;
12273 if (!TARGET_PAIRED_FLOAT)
12275 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12276 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12279 /* Add the ternary operators. */
12281 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12284 int mask = d->mask;
12286 if ((mask != 0 && (mask & target_flags) == 0)
12287 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12290 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12291 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12292 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12293 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12295 if (! (type = opaque_ftype_opaque_opaque_opaque))
12296 type = opaque_ftype_opaque_opaque_opaque
12297 = build_function_type_list (opaque_V4SI_type_node,
12298 opaque_V4SI_type_node,
12299 opaque_V4SI_type_node,
12300 opaque_V4SI_type_node,
12305 enum insn_code icode = d->icode;
12306 if (d->name == 0 || icode == CODE_FOR_nothing)
12309 type = builtin_function_type (insn_data[icode].operand[0].mode,
12310 insn_data[icode].operand[1].mode,
12311 insn_data[icode].operand[2].mode,
12312 insn_data[icode].operand[3].mode,
12316 def_builtin (d->mask, d->name, type, d->code);
12319 /* Add the binary operators. */
12321 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12323 enum machine_mode mode0, mode1, mode2;
12325 int mask = d->mask;
12327 if ((mask != 0 && (mask & target_flags) == 0)
12328 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12331 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12332 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12333 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12334 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12336 if (! (type = opaque_ftype_opaque_opaque))
12337 type = opaque_ftype_opaque_opaque
12338 = build_function_type_list (opaque_V4SI_type_node,
12339 opaque_V4SI_type_node,
12340 opaque_V4SI_type_node,
12345 enum insn_code icode = d->icode;
12346 if (d->name == 0 || icode == CODE_FOR_nothing)
12349 mode0 = insn_data[icode].operand[0].mode;
12350 mode1 = insn_data[icode].operand[1].mode;
12351 mode2 = insn_data[icode].operand[2].mode;
12353 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12355 if (! (type = v2si_ftype_v2si_qi))
12356 type = v2si_ftype_v2si_qi
12357 = build_function_type_list (opaque_V2SI_type_node,
12358 opaque_V2SI_type_node,
12363 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12364 && mode2 == QImode)
12366 if (! (type = v2si_ftype_int_qi))
12367 type = v2si_ftype_int_qi
12368 = build_function_type_list (opaque_V2SI_type_node,
12375 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12379 def_builtin (d->mask, d->name, type, d->code);
12382 /* Add the simple unary operators. */
12383 d = (struct builtin_description *) bdesc_1arg;
12384 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12386 enum machine_mode mode0, mode1;
12388 int mask = d->mask;
12390 if ((mask != 0 && (mask & target_flags) == 0)
12391 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12394 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12395 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12396 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12397 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12399 if (! (type = opaque_ftype_opaque))
12400 type = opaque_ftype_opaque
12401 = build_function_type_list (opaque_V4SI_type_node,
12402 opaque_V4SI_type_node,
12407 enum insn_code icode = d->icode;
12408 if (d->name == 0 || icode == CODE_FOR_nothing)
12411 mode0 = insn_data[icode].operand[0].mode;
12412 mode1 = insn_data[icode].operand[1].mode;
12414 if (mode0 == V2SImode && mode1 == QImode)
12416 if (! (type = v2si_ftype_qi))
12417 type = v2si_ftype_qi
12418 = build_function_type_list (opaque_V2SI_type_node,
12424 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12428 def_builtin (d->mask, d->name, type, d->code);
12433 rs6000_init_libfuncs (void)
12435 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12436 && !TARGET_POWER2 && !TARGET_POWERPC)
12438 /* AIX library routines for float->int conversion. */
12439 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12440 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12441 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12442 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12445 if (!TARGET_IEEEQUAD)
12446 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12447 if (!TARGET_XL_COMPAT)
12449 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12450 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12451 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12452 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12454 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12456 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12457 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12458 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12459 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12460 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12461 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12462 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12464 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12465 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12466 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12467 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12468 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12469 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12470 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12471 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12474 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12475 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12479 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12480 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12481 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12482 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12486 /* 32-bit SVR4 quad floating point routines. */
12488 set_optab_libfunc (add_optab, TFmode, "_q_add");
12489 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12490 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12491 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12492 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12493 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12494 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12496 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12497 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12498 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12499 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12500 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12501 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12503 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12504 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12505 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12506 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12507 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12508 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12509 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12510 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12515 /* Expand a block clear operation, and return 1 if successful. Return 0
12516 if we should let the compiler generate normal code.
12518 operands[0] is the destination
12519 operands[1] is the length
12520 operands[3] is the alignment */
12523 expand_block_clear (rtx operands[])
12525 rtx orig_dest = operands[0];
12526 rtx bytes_rtx = operands[1];
12527 rtx align_rtx = operands[3];
12528 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12529 HOST_WIDE_INT align;
12530 HOST_WIDE_INT bytes;
12535 /* If this is not a fixed size move, just call memcpy */
12539 /* This must be a fixed size alignment */
12540 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12541 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12543 /* Anything to clear? */
12544 bytes = INTVAL (bytes_rtx);
12548 /* Use the builtin memset after a point, to avoid huge code bloat.
12549 When optimize_size, avoid any significant code bloat; calling
12550 memset is about 4 instructions, so allow for one instruction to
12551 load zero and three to do clearing. */
12552 if (TARGET_ALTIVEC && align >= 128)
12554 else if (TARGET_POWERPC64 && align >= 32)
12556 else if (TARGET_SPE && align >= 64)
12561 if (optimize_size && bytes > 3 * clear_step)
12563 if (! optimize_size && bytes > 8 * clear_step)
12566 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12568 enum machine_mode mode = BLKmode;
12571 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12576 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12581 else if (bytes >= 8 && TARGET_POWERPC64
12582 /* 64-bit loads and stores require word-aligned
12584 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12589 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12590 { /* move 4 bytes */
12594 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12595 { /* move 2 bytes */
12599 else /* move 1 byte at a time */
12605 dest = adjust_address (orig_dest, mode, offset);
12607 emit_move_insn (dest, CONST0_RTX (mode));
12614 /* Expand a block move operation, and return 1 if successful. Return 0
12615 if we should let the compiler generate normal code.
12617 operands[0] is the destination
12618 operands[1] is the source
12619 operands[2] is the length
12620 operands[3] is the alignment */
12622 #define MAX_MOVE_REG 4
12625 expand_block_move (rtx operands[])
12627 rtx orig_dest = operands[0];
12628 rtx orig_src = operands[1];
12629 rtx bytes_rtx = operands[2];
12630 rtx align_rtx = operands[3];
12631 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12636 rtx stores[MAX_MOVE_REG];
12639 /* If this is not a fixed size move, just call memcpy */
12643 /* This must be a fixed size alignment */
12644 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12645 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12647 /* Anything to move? */
12648 bytes = INTVAL (bytes_rtx);
12652 /* store_one_arg depends on expand_block_move to handle at least the size of
12653 reg_parm_stack_space. */
12654 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12657 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12660 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12661 rtx (*mov) (rtx, rtx);
12663 enum machine_mode mode = BLKmode;
12666 /* Altivec first, since it will be faster than a string move
12667 when it applies, and usually not significantly larger. */
12668 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12672 gen_func.mov = gen_movv4si;
12674 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12678 gen_func.mov = gen_movv2si;
12680 else if (TARGET_STRING
12681 && bytes > 24 /* move up to 32 bytes at a time */
12687 && ! fixed_regs[10]
12688 && ! fixed_regs[11]
12689 && ! fixed_regs[12])
12691 move_bytes = (bytes > 32) ? 32 : bytes;
12692 gen_func.movmemsi = gen_movmemsi_8reg;
12694 else if (TARGET_STRING
12695 && bytes > 16 /* move up to 24 bytes at a time */
12701 && ! fixed_regs[10])
12703 move_bytes = (bytes > 24) ? 24 : bytes;
12704 gen_func.movmemsi = gen_movmemsi_6reg;
12706 else if (TARGET_STRING
12707 && bytes > 8 /* move up to 16 bytes at a time */
12711 && ! fixed_regs[8])
12713 move_bytes = (bytes > 16) ? 16 : bytes;
12714 gen_func.movmemsi = gen_movmemsi_4reg;
12716 else if (bytes >= 8 && TARGET_POWERPC64
12717 /* 64-bit loads and stores require word-aligned
12719 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12723 gen_func.mov = gen_movdi;
12725 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12726 { /* move up to 8 bytes at a time */
12727 move_bytes = (bytes > 8) ? 8 : bytes;
12728 gen_func.movmemsi = gen_movmemsi_2reg;
12730 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12731 { /* move 4 bytes */
12734 gen_func.mov = gen_movsi;
12736 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12737 { /* move 2 bytes */
12740 gen_func.mov = gen_movhi;
12742 else if (TARGET_STRING && bytes > 1)
12743 { /* move up to 4 bytes at a time */
12744 move_bytes = (bytes > 4) ? 4 : bytes;
12745 gen_func.movmemsi = gen_movmemsi_1reg;
12747 else /* move 1 byte at a time */
12751 gen_func.mov = gen_movqi;
12754 src = adjust_address (orig_src, mode, offset);
12755 dest = adjust_address (orig_dest, mode, offset);
12757 if (mode != BLKmode)
12759 rtx tmp_reg = gen_reg_rtx (mode);
12761 emit_insn ((*gen_func.mov) (tmp_reg, src));
12762 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12765 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12768 for (i = 0; i < num_reg; i++)
12769 emit_insn (stores[i]);
12773 if (mode == BLKmode)
12775 /* Move the address into scratch registers. The movmemsi
12776 patterns require zero offset. */
12777 if (!REG_P (XEXP (src, 0)))
12779 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12780 src = replace_equiv_address (src, src_reg);
12782 set_mem_size (src, GEN_INT (move_bytes));
12784 if (!REG_P (XEXP (dest, 0)))
12786 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12787 dest = replace_equiv_address (dest, dest_reg);
12789 set_mem_size (dest, GEN_INT (move_bytes));
12791 emit_insn ((*gen_func.movmemsi) (dest, src,
12792 GEN_INT (move_bytes & 31),
12801 /* Return a string to perform a load_multiple operation.
12802 operands[0] is the vector.
12803 operands[1] is the source address.
12804 operands[2] is the first destination register. */
12807 rs6000_output_load_multiple (rtx operands[3])
12809 /* We have to handle the case where the pseudo used to contain the address
12810 is assigned to one of the output registers. */
12812 int words = XVECLEN (operands[0], 0);
12815 if (XVECLEN (operands[0], 0) == 1)
12816 return "{l|lwz} %2,0(%1)";
12818 for (i = 0; i < words; i++)
12819 if (refers_to_regno_p (REGNO (operands[2]) + i,
12820 REGNO (operands[2]) + i + 1, operands[1], 0))
12824 xop[0] = GEN_INT (4 * (words-1));
12825 xop[1] = operands[1];
12826 xop[2] = operands[2];
12827 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12832 xop[0] = GEN_INT (4 * (words-1));
12833 xop[1] = operands[1];
12834 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12835 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);
12840 for (j = 0; j < words; j++)
12843 xop[0] = GEN_INT (j * 4);
12844 xop[1] = operands[1];
12845 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12846 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12848 xop[0] = GEN_INT (i * 4);
12849 xop[1] = operands[1];
12850 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12855 return "{lsi|lswi} %2,%1,%N0";
12859 /* A validation routine: say whether CODE, a condition code, and MODE
12860 match. The other alternatives either don't make sense or should
12861 never be generated. */
12864 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12866 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12867 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12868 && GET_MODE_CLASS (mode) == MODE_CC);
12870 /* These don't make sense. */
12871 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12872 || mode != CCUNSmode);
12874 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12875 || mode == CCUNSmode);
12877 gcc_assert (mode == CCFPmode
12878 || (code != ORDERED && code != UNORDERED
12879 && code != UNEQ && code != LTGT
12880 && code != UNGT && code != UNLT
12881 && code != UNGE && code != UNLE));
12883 /* These should never be generated except for
12884 flag_finite_math_only. */
12885 gcc_assert (mode != CCFPmode
12886 || flag_finite_math_only
12887 || (code != LE && code != GE
12888 && code != UNEQ && code != LTGT
12889 && code != UNGT && code != UNLT));
12891 /* These are invalid; the information is not there. */
12892 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12896 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12897 mask required to convert the result of a rotate insn into a shift
12898 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12901 includes_lshift_p (rtx shiftop, rtx andop)
12903 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12905 shift_mask <<= INTVAL (shiftop);
12907 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12910 /* Similar, but for right shift. */
12913 includes_rshift_p (rtx shiftop, rtx andop)
12915 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12917 shift_mask >>= INTVAL (shiftop);
12919 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12922 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12923 to perform a left shift. It must have exactly SHIFTOP least
12924 significant 0's, then one or more 1's, then zero or more 0's. */
12927 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12929 if (GET_CODE (andop) == CONST_INT)
12931 HOST_WIDE_INT c, lsb, shift_mask;
12933 c = INTVAL (andop);
12934 if (c == 0 || c == ~0)
12938 shift_mask <<= INTVAL (shiftop);
12940 /* Find the least significant one bit. */
12943 /* It must coincide with the LSB of the shift mask. */
12944 if (-lsb != shift_mask)
12947 /* Invert to look for the next transition (if any). */
12950 /* Remove the low group of ones (originally low group of zeros). */
12953 /* Again find the lsb, and check we have all 1's above. */
12957 else if (GET_CODE (andop) == CONST_DOUBLE
12958 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12960 HOST_WIDE_INT low, high, lsb;
12961 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12963 low = CONST_DOUBLE_LOW (andop);
12964 if (HOST_BITS_PER_WIDE_INT < 64)
12965 high = CONST_DOUBLE_HIGH (andop);
12967 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12968 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12971 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12973 shift_mask_high = ~0;
12974 if (INTVAL (shiftop) > 32)
12975 shift_mask_high <<= INTVAL (shiftop) - 32;
12977 lsb = high & -high;
12979 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12985 lsb = high & -high;
12986 return high == -lsb;
12989 shift_mask_low = ~0;
12990 shift_mask_low <<= INTVAL (shiftop);
12994 if (-lsb != shift_mask_low)
12997 if (HOST_BITS_PER_WIDE_INT < 64)
13002 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13004 lsb = high & -high;
13005 return high == -lsb;
13009 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13015 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13016 to perform a left shift. It must have SHIFTOP or more least
13017 significant 0's, with the remainder of the word 1's. */
13020 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13022 if (GET_CODE (andop) == CONST_INT)
13024 HOST_WIDE_INT c, lsb, shift_mask;
13027 shift_mask <<= INTVAL (shiftop);
13028 c = INTVAL (andop);
13030 /* Find the least significant one bit. */
13033 /* It must be covered by the shift mask.
13034 This test also rejects c == 0. */
13035 if ((lsb & shift_mask) == 0)
13038 /* Check we have all 1's above the transition, and reject all 1's. */
13039 return c == -lsb && lsb != 1;
13041 else if (GET_CODE (andop) == CONST_DOUBLE
13042 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13044 HOST_WIDE_INT low, lsb, shift_mask_low;
13046 low = CONST_DOUBLE_LOW (andop);
13048 if (HOST_BITS_PER_WIDE_INT < 64)
13050 HOST_WIDE_INT high, shift_mask_high;
13052 high = CONST_DOUBLE_HIGH (andop);
13056 shift_mask_high = ~0;
13057 if (INTVAL (shiftop) > 32)
13058 shift_mask_high <<= INTVAL (shiftop) - 32;
13060 lsb = high & -high;
13062 if ((lsb & shift_mask_high) == 0)
13065 return high == -lsb;
13071 shift_mask_low = ~0;
13072 shift_mask_low <<= INTVAL (shiftop);
13076 if ((lsb & shift_mask_low) == 0)
13079 return low == -lsb && lsb != 1;
13085 /* Return 1 if operands will generate a valid arguments to rlwimi
13086 instruction for insert with right shift in 64-bit mode. The mask may
13087 not start on the first bit or stop on the last bit because wrap-around
13088 effects of instruction do not correspond to semantics of RTL insn. */
13091 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13093 if (INTVAL (startop) > 32
13094 && INTVAL (startop) < 64
13095 && INTVAL (sizeop) > 1
13096 && INTVAL (sizeop) + INTVAL (startop) < 64
13097 && INTVAL (shiftop) > 0
13098 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13099 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13105 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13106 for lfq and stfq insns iff the registers are hard registers. */
13109 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13111 /* We might have been passed a SUBREG. */
13112 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13115 /* We might have been passed non floating point registers. */
13116 if (!FP_REGNO_P (REGNO (reg1))
13117 || !FP_REGNO_P (REGNO (reg2)))
13120 return (REGNO (reg1) == REGNO (reg2) - 1);
13123 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13124 addr1 and addr2 must be in consecutive memory locations
13125 (addr2 == addr1 + 8). */
13128 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13131 unsigned int reg1, reg2;
13132 int offset1, offset2;
13134 /* The mems cannot be volatile. */
13135 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13138 addr1 = XEXP (mem1, 0);
13139 addr2 = XEXP (mem2, 0);
13141 /* Extract an offset (if used) from the first addr. */
13142 if (GET_CODE (addr1) == PLUS)
13144 /* If not a REG, return zero. */
13145 if (GET_CODE (XEXP (addr1, 0)) != REG)
13149 reg1 = REGNO (XEXP (addr1, 0));
13150 /* The offset must be constant! */
13151 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13153 offset1 = INTVAL (XEXP (addr1, 1));
13156 else if (GET_CODE (addr1) != REG)
13160 reg1 = REGNO (addr1);
13161 /* This was a simple (mem (reg)) expression. Offset is 0. */
13165 /* And now for the second addr. */
13166 if (GET_CODE (addr2) == PLUS)
13168 /* If not a REG, return zero. */
13169 if (GET_CODE (XEXP (addr2, 0)) != REG)
13173 reg2 = REGNO (XEXP (addr2, 0));
13174 /* The offset must be constant. */
13175 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13177 offset2 = INTVAL (XEXP (addr2, 1));
13180 else if (GET_CODE (addr2) != REG)
13184 reg2 = REGNO (addr2);
13185 /* This was a simple (mem (reg)) expression. Offset is 0. */
13189 /* Both of these must have the same base register. */
13193 /* The offset for the second addr must be 8 more than the first addr. */
13194 if (offset2 != offset1 + 8)
13197 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13204 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13206 static bool eliminated = false;
13209 if (mode != SDmode)
13210 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13213 rtx mem = cfun->machine->sdmode_stack_slot;
13214 gcc_assert (mem != NULL_RTX);
13218 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13219 cfun->machine->sdmode_stack_slot = mem;
13225 if (TARGET_DEBUG_ADDR)
13227 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13228 GET_MODE_NAME (mode));
13230 fprintf (stderr, "\tNULL_RTX\n");
13239 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13241 /* Don't walk into types. */
13242 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13244 *walk_subtrees = 0;
13248 switch (TREE_CODE (*tp))
13257 case ALIGN_INDIRECT_REF:
13258 case MISALIGNED_INDIRECT_REF:
13259 case VIEW_CONVERT_EXPR:
13260 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13270 enum reload_reg_type {
13272 VECTOR_REGISTER_TYPE,
13273 OTHER_REGISTER_TYPE
13276 static enum reload_reg_type
13277 rs6000_reload_register_type (enum reg_class rclass)
13283 return GPR_REGISTER_TYPE;
13288 return VECTOR_REGISTER_TYPE;
13291 return OTHER_REGISTER_TYPE;
13295 /* Inform reload about cases where moving X with a mode MODE to a register in
13296 RCLASS requires an extra scratch or immediate register. Return the class
13297 needed for the immediate register.
13299 For VSX and Altivec, we may need a register to convert sp+offset into
13302 static enum reg_class
13303 rs6000_secondary_reload (bool in_p,
13305 enum reg_class rclass,
13306 enum machine_mode mode,
13307 secondary_reload_info *sri)
13309 enum reg_class ret = ALL_REGS;
13310 enum insn_code icode;
13311 bool default_p = false;
13313 sri->icode = CODE_FOR_nothing;
13315 /* Convert vector loads and stores into gprs to use an additional base
13317 icode = rs6000_vector_reload[mode][in_p != false];
13318 if (icode != CODE_FOR_nothing)
13321 sri->icode = CODE_FOR_nothing;
13322 sri->extra_cost = 0;
13324 if (GET_CODE (x) == MEM)
13326 rtx addr = XEXP (x, 0);
13328 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13329 an extra register in that case, but it would need an extra
13330 register if the addressing is reg+reg or (reg+reg)&(-16). */
13331 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13333 if (!legitimate_indirect_address_p (addr, false)
13334 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13336 sri->icode = icode;
13337 /* account for splitting the loads, and converting the
13338 address from reg+reg to reg. */
13339 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13340 + ((GET_CODE (addr) == AND) ? 1 : 0));
13343 /* Loads to and stores from vector registers can only do reg+reg
13344 addressing. Altivec registers can also do (reg+reg)&(-16). */
13345 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13346 || rclass == FLOAT_REGS || rclass == NO_REGS)
13348 if (!VECTOR_MEM_ALTIVEC_P (mode)
13349 && GET_CODE (addr) == AND
13350 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13351 && INTVAL (XEXP (addr, 1)) == -16
13352 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13353 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13355 sri->icode = icode;
13356 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13359 else if (!legitimate_indirect_address_p (addr, false)
13360 && (rclass == NO_REGS
13361 || !legitimate_indexed_address_p (addr, false)))
13363 sri->icode = icode;
13364 sri->extra_cost = 1;
13367 icode = CODE_FOR_nothing;
13369 /* Any other loads, including to pseudo registers which haven't been
13370 assigned to a register yet, default to require a scratch
13374 sri->icode = icode;
13375 sri->extra_cost = 2;
13378 else if (REG_P (x))
13380 int regno = true_regnum (x);
13382 icode = CODE_FOR_nothing;
13383 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13387 enum reg_class xclass = REGNO_REG_CLASS (regno);
13388 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13389 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13391 /* If memory is needed, use default_secondary_reload to create the
13393 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13406 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13408 gcc_assert (ret != ALL_REGS);
13410 if (TARGET_DEBUG_ADDR)
13413 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13415 reg_class_names[ret],
13416 in_p ? "true" : "false",
13417 reg_class_names[rclass],
13418 GET_MODE_NAME (mode));
13421 fprintf (stderr, ", default secondary reload");
13423 if (sri->icode != CODE_FOR_nothing)
13424 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13425 insn_data[sri->icode].name, sri->extra_cost);
13427 fprintf (stderr, "\n");
13435 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13436 to SP+reg addressing. */
13439 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13441 int regno = true_regnum (reg);
13442 enum machine_mode mode = GET_MODE (reg);
13443 enum reg_class rclass;
13445 rtx and_op2 = NULL_RTX;
13448 rtx scratch_or_premodify = scratch;
13452 if (TARGET_DEBUG_ADDR)
13454 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13455 store_p ? "store" : "load");
13456 fprintf (stderr, "reg:\n");
13458 fprintf (stderr, "mem:\n");
13460 fprintf (stderr, "scratch:\n");
13461 debug_rtx (scratch);
13464 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13465 gcc_assert (GET_CODE (mem) == MEM);
13466 rclass = REGNO_REG_CLASS (regno);
13467 addr = XEXP (mem, 0);
13471 /* GPRs can handle reg + small constant, all other addresses need to use
13472 the scratch register. */
13475 if (GET_CODE (addr) == AND)
13477 and_op2 = XEXP (addr, 1);
13478 addr = XEXP (addr, 0);
13481 if (GET_CODE (addr) == PRE_MODIFY)
13483 scratch_or_premodify = XEXP (addr, 0);
13484 gcc_assert (REG_P (scratch_or_premodify));
13485 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13486 addr = XEXP (addr, 1);
13489 if (GET_CODE (addr) == PLUS
13490 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13491 || and_op2 != NULL_RTX))
13493 addr_op1 = XEXP (addr, 0);
13494 addr_op2 = XEXP (addr, 1);
13495 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13497 if (!REG_P (addr_op2)
13498 && (GET_CODE (addr_op2) != CONST_INT
13499 || !satisfies_constraint_I (addr_op2)))
13501 if (TARGET_DEBUG_ADDR)
13504 "\nMove plus addr to register %s, mode = %s: ",
13505 rs6000_reg_names[REGNO (scratch)],
13506 GET_MODE_NAME (mode));
13507 debug_rtx (addr_op2);
13509 rs6000_emit_move (scratch, addr_op2, Pmode);
13510 addr_op2 = scratch;
13513 emit_insn (gen_rtx_SET (VOIDmode,
13514 scratch_or_premodify,
13515 gen_rtx_PLUS (Pmode,
13519 addr = scratch_or_premodify;
13520 scratch_or_premodify = scratch;
13522 else if (!legitimate_indirect_address_p (addr, false)
13523 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13525 if (TARGET_DEBUG_ADDR)
13527 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13528 rs6000_reg_names[REGNO (scratch_or_premodify)],
13529 GET_MODE_NAME (mode));
13532 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13533 addr = scratch_or_premodify;
13534 scratch_or_premodify = scratch;
13538 /* Float/Altivec registers can only handle reg+reg addressing. Move
13539 other addresses into a scratch register. */
13544 /* With float regs, we need to handle the AND ourselves, since we can't
13545 use the Altivec instruction with an implicit AND -16. Allow scalar
13546 loads to float registers to use reg+offset even if VSX. */
13547 if (GET_CODE (addr) == AND
13548 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13549 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13550 || INTVAL (XEXP (addr, 1)) != -16
13551 || !VECTOR_MEM_ALTIVEC_P (mode)))
13553 and_op2 = XEXP (addr, 1);
13554 addr = XEXP (addr, 0);
13557 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13558 as the address later. */
13559 if (GET_CODE (addr) == PRE_MODIFY
13560 && (!VECTOR_MEM_VSX_P (mode)
13561 || and_op2 != NULL_RTX
13562 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13564 scratch_or_premodify = XEXP (addr, 0);
13565 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13567 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13568 addr = XEXP (addr, 1);
13571 if (legitimate_indirect_address_p (addr, false) /* reg */
13572 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13573 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13574 || (GET_CODE (addr) == AND /* Altivec memory */
13575 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13576 && INTVAL (XEXP (addr, 1)) == -16
13577 && VECTOR_MEM_ALTIVEC_P (mode))
13578 || (rclass == FLOAT_REGS /* legacy float mem */
13579 && GET_MODE_SIZE (mode) == 8
13580 && and_op2 == NULL_RTX
13581 && scratch_or_premodify == scratch
13582 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13585 else if (GET_CODE (addr) == PLUS)
13587 addr_op1 = XEXP (addr, 0);
13588 addr_op2 = XEXP (addr, 1);
13589 gcc_assert (REG_P (addr_op1));
13591 if (TARGET_DEBUG_ADDR)
13593 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13594 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13595 debug_rtx (addr_op2);
13597 rs6000_emit_move (scratch, addr_op2, Pmode);
13598 emit_insn (gen_rtx_SET (VOIDmode,
13599 scratch_or_premodify,
13600 gen_rtx_PLUS (Pmode,
13603 addr = scratch_or_premodify;
13604 scratch_or_premodify = scratch;
13607 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13608 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13610 if (TARGET_DEBUG_ADDR)
13612 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13613 rs6000_reg_names[REGNO (scratch_or_premodify)],
13614 GET_MODE_NAME (mode));
13618 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13619 addr = scratch_or_premodify;
13620 scratch_or_premodify = scratch;
13624 gcc_unreachable ();
13629 gcc_unreachable ();
13632 /* If the original address involved a pre-modify that we couldn't use the VSX
13633 memory instruction with update, and we haven't taken care of already,
13634 store the address in the pre-modify register and use that as the
13636 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13638 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13639 addr = scratch_or_premodify;
13642 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13643 memory instruction, recreate the AND now, including the clobber which is
13644 generated by the general ANDSI3/ANDDI3 patterns for the
13645 andi. instruction. */
13646 if (and_op2 != NULL_RTX)
13648 if (! legitimate_indirect_address_p (addr, false))
13650 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13654 if (TARGET_DEBUG_ADDR)
13656 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13657 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13658 debug_rtx (and_op2);
13661 and_rtx = gen_rtx_SET (VOIDmode,
13663 gen_rtx_AND (Pmode,
13667 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13668 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13669 gen_rtvec (2, and_rtx, cc_clobber)));
13673 /* Adjust the address if it changed. */
13674 if (addr != XEXP (mem, 0))
13676 mem = change_address (mem, mode, addr);
13677 if (TARGET_DEBUG_ADDR)
13678 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13681 /* Now create the move. */
13683 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13685 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13690 /* Target hook to return the cover classes for Integrated Register Allocator.
13691 Cover classes is a set of non-intersected register classes covering all hard
13692 registers used for register allocation purpose. Any move between two
13693 registers of a cover class should be cheaper than load or store of the
13694 registers. The value is array of register classes with LIM_REG_CLASSES used
13697 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13698 account for the Altivec and Floating registers being subsets of the VSX
13699 register set under VSX, but distinct register sets on pre-VSX machines. */
13701 static const enum reg_class *
13702 rs6000_ira_cover_classes (void)
13704 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13705 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13707 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13710 /* Allocate a 64-bit stack slot to be used for copying SDmode
13711 values through if this function has any SDmode references. */
13714 rs6000_alloc_sdmode_stack_slot (void)
13718 gimple_stmt_iterator gsi;
13720 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13723 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13725 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13728 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13729 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13735 /* Check for any SDmode parameters of the function. */
13736 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13738 if (TREE_TYPE (t) == error_mark_node)
13741 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13742 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13744 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13745 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13753 rs6000_instantiate_decls (void)
13755 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13756 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13759 /* Given an rtx X being reloaded into a reg required to be
13760 in class CLASS, return the class of reg to actually use.
13761 In general this is just CLASS; but on some machines
13762 in some cases it is preferable to use a more restrictive class.
13764 On the RS/6000, we have to return NO_REGS when we want to reload a
13765 floating-point CONST_DOUBLE to force it to be copied to memory.
13767 We also don't want to reload integer values into floating-point
13768 registers if we can at all help it. In fact, this can
13769 cause reload to die, if it tries to generate a reload of CTR
13770 into a FP register and discovers it doesn't have the memory location
13773 ??? Would it be a good idea to have reload do the converse, that is
13774 try to reload floating modes into FP registers if possible?
13777 static enum reg_class
13778 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13780 enum machine_mode mode = GET_MODE (x);
13782 if (VECTOR_UNIT_VSX_P (mode)
13783 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13786 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13787 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13788 && easy_vector_constant (x, mode))
13789 return ALTIVEC_REGS;
13791 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13794 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13795 return GENERAL_REGS;
13797 /* For VSX, prefer the traditional registers for DF if the address is of the
13798 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13799 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13801 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13803 if (mode == DFmode && GET_CODE (x) == MEM)
13805 rtx addr = XEXP (x, 0);
13807 if (legitimate_indirect_address_p (addr, false)) /* reg */
13810 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13813 if (GET_CODE (addr) == PRE_MODIFY
13814 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13820 if (VECTOR_UNIT_ALTIVEC_P (mode))
13821 return ALTIVEC_REGS;
13829 /* Debug version of rs6000_preferred_reload_class. */
13830 static enum reg_class
13831 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13833 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13836 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13838 reg_class_names[ret], reg_class_names[rclass],
13839 GET_MODE_NAME (GET_MODE (x)));
13845 /* If we are copying between FP or AltiVec registers and anything else, we need
13846 a memory location. The exception is when we are targeting ppc64 and the
13847 move to/from fpr to gpr instructions are available. Also, under VSX, you
13848 can copy vector registers from the FP register set to the Altivec register
13849 set and vice versa. */
13852 rs6000_secondary_memory_needed (enum reg_class class1,
13853 enum reg_class class2,
13854 enum machine_mode mode)
13856 if (class1 == class2)
13859 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13860 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13861 between these classes. But we need memory for other things that can go in
13862 FLOAT_REGS like SFmode. */
13864 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13865 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13866 || class1 == FLOAT_REGS))
13867 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13868 && class2 != FLOAT_REGS);
13870 if (class1 == VSX_REGS || class2 == VSX_REGS)
13873 if (class1 == FLOAT_REGS
13874 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13875 || ((mode != DFmode)
13876 && (mode != DDmode)
13877 && (mode != DImode))))
13880 if (class2 == FLOAT_REGS
13881 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13882 || ((mode != DFmode)
13883 && (mode != DDmode)
13884 && (mode != DImode))))
13887 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13893 /* Debug version of rs6000_secondary_memory_needed. */
13895 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13896 enum reg_class class2,
13897 enum machine_mode mode)
13899 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13902 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13903 "class2 = %s, mode = %s\n",
13904 ret ? "true" : "false", reg_class_names[class1],
13905 reg_class_names[class2], GET_MODE_NAME (mode));
13910 /* Return the register class of a scratch register needed to copy IN into
13911 or out of a register in RCLASS in MODE. If it can be done directly,
13912 NO_REGS is returned. */
13914 static enum reg_class
13915 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13920 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13922 && MACHOPIC_INDIRECT
13926 /* We cannot copy a symbolic operand directly into anything
13927 other than BASE_REGS for TARGET_ELF. So indicate that a
13928 register from BASE_REGS is needed as an intermediate
13931 On Darwin, pic addresses require a load from memory, which
13932 needs a base register. */
13933 if (rclass != BASE_REGS
13934 && (GET_CODE (in) == SYMBOL_REF
13935 || GET_CODE (in) == HIGH
13936 || GET_CODE (in) == LABEL_REF
13937 || GET_CODE (in) == CONST))
13941 if (GET_CODE (in) == REG)
13943 regno = REGNO (in);
13944 if (regno >= FIRST_PSEUDO_REGISTER)
13946 regno = true_regnum (in);
13947 if (regno >= FIRST_PSEUDO_REGISTER)
13951 else if (GET_CODE (in) == SUBREG)
13953 regno = true_regnum (in);
13954 if (regno >= FIRST_PSEUDO_REGISTER)
13960 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13962 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13963 || (regno >= 0 && INT_REGNO_P (regno)))
13966 /* Constants, memory, and FP registers can go into FP registers. */
13967 if ((regno == -1 || FP_REGNO_P (regno))
13968 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13969 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13971 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13974 && (regno == -1 || VSX_REGNO_P (regno))
13975 && VSX_REG_CLASS_P (rclass))
13978 /* Memory, and AltiVec registers can go into AltiVec registers. */
13979 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13980 && rclass == ALTIVEC_REGS)
13983 /* We can copy among the CR registers. */
13984 if ((rclass == CR_REGS || rclass == CR0_REGS)
13985 && regno >= 0 && CR_REGNO_P (regno))
13988 /* Otherwise, we need GENERAL_REGS. */
13989 return GENERAL_REGS;
13992 /* Debug version of rs6000_secondary_reload_class. */
13993 static enum reg_class
13994 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13995 enum machine_mode mode, rtx in)
13997 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13999 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14000 "mode = %s, input rtx:\n",
14001 reg_class_names[ret], reg_class_names[rclass],
14002 GET_MODE_NAME (mode));
14008 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14011 rs6000_cannot_change_mode_class (enum machine_mode from,
14012 enum machine_mode to,
14013 enum reg_class rclass)
14015 unsigned from_size = GET_MODE_SIZE (from);
14016 unsigned to_size = GET_MODE_SIZE (to);
14018 if (from_size != to_size)
14020 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14021 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14022 && reg_classes_intersect_p (xclass, rclass));
14025 if (TARGET_E500_DOUBLE
14026 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14027 || (((to) == TFmode) + ((from) == TFmode)) == 1
14028 || (((to) == DDmode) + ((from) == DDmode)) == 1
14029 || (((to) == TDmode) + ((from) == TDmode)) == 1
14030 || (((to) == DImode) + ((from) == DImode)) == 1))
14033 /* Since the VSX register set includes traditional floating point registers
14034 and altivec registers, just check for the size being different instead of
14035 trying to check whether the modes are vector modes. Otherwise it won't
14036 allow say DF and DI to change classes. */
14037 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14038 return (from_size != 8 && from_size != 16);
14040 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14041 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14044 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14045 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14051 /* Debug version of rs6000_cannot_change_mode_class. */
14053 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14054 enum machine_mode to,
14055 enum reg_class rclass)
14057 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14060 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14061 "to = %s, rclass = %s\n",
14062 ret ? "true" : "false",
14063 GET_MODE_NAME (from), GET_MODE_NAME (to),
14064 reg_class_names[rclass]);
14069 /* Given a comparison operation, return the bit number in CCR to test. We
14070 know this is a valid comparison.
14072 SCC_P is 1 if this is for an scc. That means that %D will have been
14073 used instead of %C, so the bits will be in different places.
14075 Return -1 if OP isn't a valid comparison for some reason. */
14078 ccr_bit (rtx op, int scc_p)
14080 enum rtx_code code = GET_CODE (op);
14081 enum machine_mode cc_mode;
14086 if (!COMPARISON_P (op))
14089 reg = XEXP (op, 0);
14091 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14093 cc_mode = GET_MODE (reg);
14094 cc_regnum = REGNO (reg);
14095 base_bit = 4 * (cc_regnum - CR0_REGNO);
14097 validate_condition_mode (code, cc_mode);
14099 /* When generating a sCOND operation, only positive conditions are
14102 || code == EQ || code == GT || code == LT || code == UNORDERED
14103 || code == GTU || code == LTU);
14108 return scc_p ? base_bit + 3 : base_bit + 2;
14110 return base_bit + 2;
14111 case GT: case GTU: case UNLE:
14112 return base_bit + 1;
14113 case LT: case LTU: case UNGE:
14115 case ORDERED: case UNORDERED:
14116 return base_bit + 3;
14119 /* If scc, we will have done a cror to put the bit in the
14120 unordered position. So test that bit. For integer, this is ! LT
14121 unless this is an scc insn. */
14122 return scc_p ? base_bit + 3 : base_bit;
14125 return scc_p ? base_bit + 3 : base_bit + 1;
14128 gcc_unreachable ();
14132 /* Return the GOT register. */
14135 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14137 /* The second flow pass currently (June 1999) can't update
14138 regs_ever_live without disturbing other parts of the compiler, so
14139 update it here to make the prolog/epilogue code happy. */
14140 if (!can_create_pseudo_p ()
14141 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14142 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14144 crtl->uses_pic_offset_table = 1;
14146 return pic_offset_table_rtx;
14149 /* Function to init struct machine_function.
14150 This will be called, via a pointer variable,
14151 from push_function_context. */
14153 static struct machine_function *
14154 rs6000_init_machine_status (void)
14156 return GGC_CNEW (machine_function);
14159 /* These macros test for integers and extract the low-order bits. */
14161 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14162 && GET_MODE (X) == VOIDmode)
14164 #define INT_LOWPART(X) \
14165 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14168 extract_MB (rtx op)
14171 unsigned long val = INT_LOWPART (op);
14173 /* If the high bit is zero, the value is the first 1 bit we find
14175 if ((val & 0x80000000) == 0)
14177 gcc_assert (val & 0xffffffff);
14180 while (((val <<= 1) & 0x80000000) == 0)
14185 /* If the high bit is set and the low bit is not, or the mask is all
14186 1's, the value is zero. */
14187 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14190 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14193 while (((val >>= 1) & 1) != 0)
14200 extract_ME (rtx op)
14203 unsigned long val = INT_LOWPART (op);
14205 /* If the low bit is zero, the value is the first 1 bit we find from
14207 if ((val & 1) == 0)
14209 gcc_assert (val & 0xffffffff);
14212 while (((val >>= 1) & 1) == 0)
14218 /* If the low bit is set and the high bit is not, or the mask is all
14219 1's, the value is 31. */
14220 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14223 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14226 while (((val <<= 1) & 0x80000000) != 0)
14232 /* Locate some local-dynamic symbol still in use by this function
14233 so that we can print its name in some tls_ld pattern. */
14235 static const char *
14236 rs6000_get_some_local_dynamic_name (void)
14240 if (cfun->machine->some_ld_name)
14241 return cfun->machine->some_ld_name;
14243 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14245 && for_each_rtx (&PATTERN (insn),
14246 rs6000_get_some_local_dynamic_name_1, 0))
14247 return cfun->machine->some_ld_name;
14249 gcc_unreachable ();
14252 /* Helper function for rs6000_get_some_local_dynamic_name. */
14255 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14259 if (GET_CODE (x) == SYMBOL_REF)
14261 const char *str = XSTR (x, 0);
14262 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14264 cfun->machine->some_ld_name = str;
14272 /* Write out a function code label. */
14275 rs6000_output_function_entry (FILE *file, const char *fname)
14277 if (fname[0] != '.')
14279 switch (DEFAULT_ABI)
14282 gcc_unreachable ();
14288 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14297 RS6000_OUTPUT_BASENAME (file, fname);
14299 assemble_name (file, fname);
14302 /* Print an operand. Recognize special options, documented below. */
14305 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14306 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14308 #define SMALL_DATA_RELOC "sda21"
14309 #define SMALL_DATA_REG 0
14313 print_operand (FILE *file, rtx x, int code)
14317 unsigned HOST_WIDE_INT uval;
14322 /* Write out an instruction after the call which may be replaced
14323 with glue code by the loader. This depends on the AIX version. */
14324 asm_fprintf (file, RS6000_CALL_GLUE);
14327 /* %a is output_address. */
14330 /* If X is a constant integer whose low-order 5 bits are zero,
14331 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14332 in the AIX assembler where "sri" with a zero shift count
14333 writes a trash instruction. */
14334 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14341 /* If constant, low-order 16 bits of constant, unsigned.
14342 Otherwise, write normally. */
14344 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14346 print_operand (file, x, 0);
14350 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14351 for 64-bit mask direction. */
14352 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14355 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14359 /* X is a CR register. Print the number of the GT bit of the CR. */
14360 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14361 output_operand_lossage ("invalid %%c value");
14363 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14367 /* Like 'J' but get to the GT bit only. */
14368 gcc_assert (GET_CODE (x) == REG);
14370 /* Bit 1 is GT bit. */
14371 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14373 /* Add one for shift count in rlinm for scc. */
14374 fprintf (file, "%d", i + 1);
14378 /* X is a CR register. Print the number of the EQ bit of the CR */
14379 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14380 output_operand_lossage ("invalid %%E value");
14382 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14386 /* X is a CR register. Print the shift count needed to move it
14387 to the high-order four bits. */
14388 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14389 output_operand_lossage ("invalid %%f value");
14391 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14395 /* Similar, but print the count for the rotate in the opposite
14397 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14398 output_operand_lossage ("invalid %%F value");
14400 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14404 /* X is a constant integer. If it is negative, print "m",
14405 otherwise print "z". This is to make an aze or ame insn. */
14406 if (GET_CODE (x) != CONST_INT)
14407 output_operand_lossage ("invalid %%G value");
14408 else if (INTVAL (x) >= 0)
14415 /* If constant, output low-order five bits. Otherwise, write
14418 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14420 print_operand (file, x, 0);
14424 /* If constant, output low-order six bits. Otherwise, write
14427 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14429 print_operand (file, x, 0);
14433 /* Print `i' if this is a constant, else nothing. */
14439 /* Write the bit number in CCR for jump. */
14440 i = ccr_bit (x, 0);
14442 output_operand_lossage ("invalid %%j code");
14444 fprintf (file, "%d", i);
14448 /* Similar, but add one for shift count in rlinm for scc and pass
14449 scc flag to `ccr_bit'. */
14450 i = ccr_bit (x, 1);
14452 output_operand_lossage ("invalid %%J code");
14454 /* If we want bit 31, write a shift count of zero, not 32. */
14455 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14459 /* X must be a constant. Write the 1's complement of the
14462 output_operand_lossage ("invalid %%k value");
14464 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14468 /* X must be a symbolic constant on ELF. Write an
14469 expression suitable for an 'addi' that adds in the low 16
14470 bits of the MEM. */
14471 if (GET_CODE (x) != CONST)
14473 print_operand_address (file, x);
14474 fputs ("@l", file);
14478 if (GET_CODE (XEXP (x, 0)) != PLUS
14479 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14480 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14481 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14482 output_operand_lossage ("invalid %%K value");
14483 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14484 fputs ("@l", file);
14485 /* For GNU as, there must be a non-alphanumeric character
14486 between 'l' and the number. The '-' is added by
14487 print_operand() already. */
14488 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14490 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14494 /* %l is output_asm_label. */
14497 /* Write second word of DImode or DFmode reference. Works on register
14498 or non-indexed memory only. */
14499 if (GET_CODE (x) == REG)
14500 fputs (reg_names[REGNO (x) + 1], file);
14501 else if (GET_CODE (x) == MEM)
14503 /* Handle possible auto-increment. Since it is pre-increment and
14504 we have already done it, we can just use an offset of word. */
14505 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14506 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14507 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14509 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14510 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14513 output_address (XEXP (adjust_address_nv (x, SImode,
14517 if (small_data_operand (x, GET_MODE (x)))
14518 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14519 reg_names[SMALL_DATA_REG]);
14524 /* MB value for a mask operand. */
14525 if (! mask_operand (x, SImode))
14526 output_operand_lossage ("invalid %%m value");
14528 fprintf (file, "%d", extract_MB (x));
14532 /* ME value for a mask operand. */
14533 if (! mask_operand (x, SImode))
14534 output_operand_lossage ("invalid %%M value");
14536 fprintf (file, "%d", extract_ME (x));
14539 /* %n outputs the negative of its operand. */
14542 /* Write the number of elements in the vector times 4. */
14543 if (GET_CODE (x) != PARALLEL)
14544 output_operand_lossage ("invalid %%N value");
14546 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14550 /* Similar, but subtract 1 first. */
14551 if (GET_CODE (x) != PARALLEL)
14552 output_operand_lossage ("invalid %%O value");
14554 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14558 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14560 || INT_LOWPART (x) < 0
14561 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14562 output_operand_lossage ("invalid %%p value");
14564 fprintf (file, "%d", i);
14568 /* The operand must be an indirect memory reference. The result
14569 is the register name. */
14570 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14571 || REGNO (XEXP (x, 0)) >= 32)
14572 output_operand_lossage ("invalid %%P value");
14574 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14578 /* This outputs the logical code corresponding to a boolean
14579 expression. The expression may have one or both operands
14580 negated (if one, only the first one). For condition register
14581 logical operations, it will also treat the negated
14582 CR codes as NOTs, but not handle NOTs of them. */
14584 const char *const *t = 0;
14586 enum rtx_code code = GET_CODE (x);
14587 static const char * const tbl[3][3] = {
14588 { "and", "andc", "nor" },
14589 { "or", "orc", "nand" },
14590 { "xor", "eqv", "xor" } };
14594 else if (code == IOR)
14596 else if (code == XOR)
14599 output_operand_lossage ("invalid %%q value");
14601 if (GET_CODE (XEXP (x, 0)) != NOT)
14605 if (GET_CODE (XEXP (x, 1)) == NOT)
14623 /* X is a CR register. Print the mask for `mtcrf'. */
14624 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14625 output_operand_lossage ("invalid %%R value");
14627 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14631 /* Low 5 bits of 32 - value */
14633 output_operand_lossage ("invalid %%s value");
14635 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14639 /* PowerPC64 mask position. All 0's is excluded.
14640 CONST_INT 32-bit mask is considered sign-extended so any
14641 transition must occur within the CONST_INT, not on the boundary. */
14642 if (! mask64_operand (x, DImode))
14643 output_operand_lossage ("invalid %%S value");
14645 uval = INT_LOWPART (x);
14647 if (uval & 1) /* Clear Left */
14649 #if HOST_BITS_PER_WIDE_INT > 64
14650 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14654 else /* Clear Right */
14657 #if HOST_BITS_PER_WIDE_INT > 64
14658 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14664 gcc_assert (i >= 0);
14665 fprintf (file, "%d", i);
14669 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14670 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14672 /* Bit 3 is OV bit. */
14673 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14675 /* If we want bit 31, write a shift count of zero, not 32. */
14676 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14680 /* Print the symbolic name of a branch target register. */
14681 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14682 && REGNO (x) != CTR_REGNO))
14683 output_operand_lossage ("invalid %%T value");
14684 else if (REGNO (x) == LR_REGNO)
14685 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14687 fputs ("ctr", file);
14691 /* High-order 16 bits of constant for use in unsigned operand. */
14693 output_operand_lossage ("invalid %%u value");
14695 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14696 (INT_LOWPART (x) >> 16) & 0xffff);
14700 /* High-order 16 bits of constant for use in signed operand. */
14702 output_operand_lossage ("invalid %%v value");
14704 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14705 (INT_LOWPART (x) >> 16) & 0xffff);
14709 /* Print `u' if this has an auto-increment or auto-decrement. */
14710 if (GET_CODE (x) == MEM
14711 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14712 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14713 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14718 /* Print the trap code for this operand. */
14719 switch (GET_CODE (x))
14722 fputs ("eq", file); /* 4 */
14725 fputs ("ne", file); /* 24 */
14728 fputs ("lt", file); /* 16 */
14731 fputs ("le", file); /* 20 */
14734 fputs ("gt", file); /* 8 */
14737 fputs ("ge", file); /* 12 */
14740 fputs ("llt", file); /* 2 */
14743 fputs ("lle", file); /* 6 */
14746 fputs ("lgt", file); /* 1 */
14749 fputs ("lge", file); /* 5 */
14752 gcc_unreachable ();
14757 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14760 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14761 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14763 print_operand (file, x, 0);
14767 /* MB value for a PowerPC64 rldic operand. */
14768 val = (GET_CODE (x) == CONST_INT
14769 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14774 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14775 if ((val <<= 1) < 0)
14778 #if HOST_BITS_PER_WIDE_INT == 32
14779 if (GET_CODE (x) == CONST_INT && i >= 0)
14780 i += 32; /* zero-extend high-part was all 0's */
14781 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14783 val = CONST_DOUBLE_LOW (x);
14789 for ( ; i < 64; i++)
14790 if ((val <<= 1) < 0)
14795 fprintf (file, "%d", i + 1);
14799 /* X is a FPR or Altivec register used in a VSX context. */
14800 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14801 output_operand_lossage ("invalid %%x value");
14804 int reg = REGNO (x);
14805 int vsx_reg = (FP_REGNO_P (reg)
14807 : reg - FIRST_ALTIVEC_REGNO + 32);
14809 #ifdef TARGET_REGNAMES
14810 if (TARGET_REGNAMES)
14811 fprintf (file, "%%vs%d", vsx_reg);
14814 fprintf (file, "%d", vsx_reg);
14819 if (GET_CODE (x) == MEM
14820 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14821 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14822 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14827 /* Like 'L', for third word of TImode */
14828 if (GET_CODE (x) == REG)
14829 fputs (reg_names[REGNO (x) + 2], file);
14830 else if (GET_CODE (x) == MEM)
14832 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14833 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14834 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14835 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14836 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14838 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14839 if (small_data_operand (x, GET_MODE (x)))
14840 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14841 reg_names[SMALL_DATA_REG]);
14846 /* X is a SYMBOL_REF. Write out the name preceded by a
14847 period and without any trailing data in brackets. Used for function
14848 names. If we are configured for System V (or the embedded ABI) on
14849 the PowerPC, do not emit the period, since those systems do not use
14850 TOCs and the like. */
14851 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14853 /* Mark the decl as referenced so that cgraph will output the
14855 if (SYMBOL_REF_DECL (x))
14856 mark_decl_referenced (SYMBOL_REF_DECL (x));
14858 /* For macho, check to see if we need a stub. */
14861 const char *name = XSTR (x, 0);
14863 if (MACHOPIC_INDIRECT
14864 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14865 name = machopic_indirection_name (x, /*stub_p=*/true);
14867 assemble_name (file, name);
14869 else if (!DOT_SYMBOLS)
14870 assemble_name (file, XSTR (x, 0));
14872 rs6000_output_function_entry (file, XSTR (x, 0));
14876 /* Like 'L', for last word of TImode. */
14877 if (GET_CODE (x) == REG)
14878 fputs (reg_names[REGNO (x) + 3], file);
14879 else if (GET_CODE (x) == MEM)
14881 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14882 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14883 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14884 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14885 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14887 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14888 if (small_data_operand (x, GET_MODE (x)))
14889 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14890 reg_names[SMALL_DATA_REG]);
14894 /* Print AltiVec or SPE memory operand. */
14899 gcc_assert (GET_CODE (x) == MEM);
14903 /* Ugly hack because %y is overloaded. */
14904 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14905 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14906 || GET_MODE (x) == TFmode
14907 || GET_MODE (x) == TImode))
14909 /* Handle [reg]. */
14910 if (GET_CODE (tmp) == REG)
14912 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14915 /* Handle [reg+UIMM]. */
14916 else if (GET_CODE (tmp) == PLUS &&
14917 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14921 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14923 x = INTVAL (XEXP (tmp, 1));
14924 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14928 /* Fall through. Must be [reg+reg]. */
14930 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14931 && GET_CODE (tmp) == AND
14932 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14933 && INTVAL (XEXP (tmp, 1)) == -16)
14934 tmp = XEXP (tmp, 0);
14935 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14936 && GET_CODE (tmp) == PRE_MODIFY)
14937 tmp = XEXP (tmp, 1);
14938 if (GET_CODE (tmp) == REG)
14939 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14942 if (!GET_CODE (tmp) == PLUS
14943 || !REG_P (XEXP (tmp, 0))
14944 || !REG_P (XEXP (tmp, 1)))
14946 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14950 if (REGNO (XEXP (tmp, 0)) == 0)
14951 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14952 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14954 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14955 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14961 if (GET_CODE (x) == REG)
14962 fprintf (file, "%s", reg_names[REGNO (x)]);
14963 else if (GET_CODE (x) == MEM)
14965 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14966 know the width from the mode. */
14967 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14968 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14969 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14970 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14971 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14972 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14973 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14974 output_address (XEXP (XEXP (x, 0), 1));
14976 output_address (XEXP (x, 0));
14979 output_addr_const (file, x);
14983 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14987 output_operand_lossage ("invalid %%xn code");
14991 /* Print the address of an operand. */
14994 print_operand_address (FILE *file, rtx x)
14996 if (GET_CODE (x) == REG)
14997 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14998 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14999 || GET_CODE (x) == LABEL_REF)
15001 output_addr_const (file, x);
15002 if (small_data_operand (x, GET_MODE (x)))
15003 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15004 reg_names[SMALL_DATA_REG]);
15006 gcc_assert (!TARGET_TOC);
15008 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15010 gcc_assert (REG_P (XEXP (x, 0)));
15011 if (REGNO (XEXP (x, 0)) == 0)
15012 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15013 reg_names[ REGNO (XEXP (x, 0)) ]);
15015 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15016 reg_names[ REGNO (XEXP (x, 1)) ]);
15018 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15019 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15020 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15022 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15023 && CONSTANT_P (XEXP (x, 1)))
15025 output_addr_const (file, XEXP (x, 1));
15026 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15030 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15031 && CONSTANT_P (XEXP (x, 1)))
15033 fprintf (file, "lo16(");
15034 output_addr_const (file, XEXP (x, 1));
15035 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15038 else if (legitimate_constant_pool_address_p (x))
15040 output_addr_const (file, XEXP (x, 1));
15041 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15044 gcc_unreachable ();
15047 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15050 rs6000_output_addr_const_extra (FILE *file, rtx x)
15052 if (GET_CODE (x) == UNSPEC)
15053 switch (XINT (x, 1))
15055 case UNSPEC_TOCREL:
15056 x = XVECEXP (x, 0, 0);
15057 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15058 output_addr_const (file, x);
15059 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15062 assemble_name (file, toc_label_name);
15064 else if (TARGET_ELF)
15065 fputs ("@toc", file);
15069 case UNSPEC_MACHOPIC_OFFSET:
15070 output_addr_const (file, XVECEXP (x, 0, 0));
15072 machopic_output_function_base_name (file);
15079 /* Target hook for assembling integer objects. The PowerPC version has
15080 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15081 is defined. It also needs to handle DI-mode objects on 64-bit
15085 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15087 #ifdef RELOCATABLE_NEEDS_FIXUP
15088 /* Special handling for SI values. */
15089 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15091 static int recurse = 0;
15093 /* For -mrelocatable, we mark all addresses that need to be fixed up
15094 in the .fixup section. */
15095 if (TARGET_RELOCATABLE
15096 && in_section != toc_section
15097 && in_section != text_section
15098 && !unlikely_text_section_p (in_section)
15100 && GET_CODE (x) != CONST_INT
15101 && GET_CODE (x) != CONST_DOUBLE
15107 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15109 ASM_OUTPUT_LABEL (asm_out_file, buf);
15110 fprintf (asm_out_file, "\t.long\t(");
15111 output_addr_const (asm_out_file, x);
15112 fprintf (asm_out_file, ")@fixup\n");
15113 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15114 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15115 fprintf (asm_out_file, "\t.long\t");
15116 assemble_name (asm_out_file, buf);
15117 fprintf (asm_out_file, "\n\t.previous\n");
15121 /* Remove initial .'s to turn a -mcall-aixdesc function
15122 address into the address of the descriptor, not the function
15124 else if (GET_CODE (x) == SYMBOL_REF
15125 && XSTR (x, 0)[0] == '.'
15126 && DEFAULT_ABI == ABI_AIX)
15128 const char *name = XSTR (x, 0);
15129 while (*name == '.')
15132 fprintf (asm_out_file, "\t.long\t%s\n", name);
15136 #endif /* RELOCATABLE_NEEDS_FIXUP */
15137 return default_assemble_integer (x, size, aligned_p);
15140 #ifdef HAVE_GAS_HIDDEN
15141 /* Emit an assembler directive to set symbol visibility for DECL to
15142 VISIBILITY_TYPE. */
15145 rs6000_assemble_visibility (tree decl, int vis)
15147 /* Functions need to have their entry point symbol visibility set as
15148 well as their descriptor symbol visibility. */
15149 if (DEFAULT_ABI == ABI_AIX
15151 && TREE_CODE (decl) == FUNCTION_DECL)
15153 static const char * const visibility_types[] = {
15154 NULL, "internal", "hidden", "protected"
15157 const char *name, *type;
15159 name = ((* targetm.strip_name_encoding)
15160 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15161 type = visibility_types[vis];
15163 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15164 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15167 default_assemble_visibility (decl, vis);
15172 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15174 /* Reversal of FP compares takes care -- an ordered compare
15175 becomes an unordered compare and vice versa. */
15176 if (mode == CCFPmode
15177 && (!flag_finite_math_only
15178 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15179 || code == UNEQ || code == LTGT))
15180 return reverse_condition_maybe_unordered (code);
15182 return reverse_condition (code);
15185 /* Generate a compare for CODE. Return a brand-new rtx that
15186 represents the result of the compare. */
15189 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15191 enum machine_mode comp_mode;
15192 rtx compare_result;
15193 enum rtx_code code = GET_CODE (cmp);
15194 rtx op0 = XEXP (cmp, 0);
15195 rtx op1 = XEXP (cmp, 1);
15197 if (FLOAT_MODE_P (mode))
15198 comp_mode = CCFPmode;
15199 else if (code == GTU || code == LTU
15200 || code == GEU || code == LEU)
15201 comp_mode = CCUNSmode;
15202 else if ((code == EQ || code == NE)
15203 && GET_CODE (op0) == SUBREG
15204 && GET_CODE (op1) == SUBREG
15205 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15206 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15207 /* These are unsigned values, perhaps there will be a later
15208 ordering compare that can be shared with this one.
15209 Unfortunately we cannot detect the signedness of the operands
15210 for non-subregs. */
15211 comp_mode = CCUNSmode;
15213 comp_mode = CCmode;
15215 /* First, the compare. */
15216 compare_result = gen_reg_rtx (comp_mode);
15218 /* E500 FP compare instructions on the GPRs. Yuck! */
15219 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15220 && FLOAT_MODE_P (mode))
15222 rtx cmp, or_result, compare_result2;
15223 enum machine_mode op_mode = GET_MODE (op0);
15225 if (op_mode == VOIDmode)
15226 op_mode = GET_MODE (op1);
15228 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15229 This explains the following mess. */
15233 case EQ: case UNEQ: case NE: case LTGT:
15237 cmp = (flag_finite_math_only && !flag_trapping_math)
15238 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15239 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15243 cmp = (flag_finite_math_only && !flag_trapping_math)
15244 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15245 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15249 cmp = (flag_finite_math_only && !flag_trapping_math)
15250 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15251 : gen_cmptfeq_gpr (compare_result, op0, op1);
15255 gcc_unreachable ();
15259 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15263 cmp = (flag_finite_math_only && !flag_trapping_math)
15264 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15265 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15269 cmp = (flag_finite_math_only && !flag_trapping_math)
15270 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15271 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15275 cmp = (flag_finite_math_only && !flag_trapping_math)
15276 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15277 : gen_cmptfgt_gpr (compare_result, op0, op1);
15281 gcc_unreachable ();
15285 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15289 cmp = (flag_finite_math_only && !flag_trapping_math)
15290 ? gen_tstsflt_gpr (compare_result, op0, op1)
15291 : gen_cmpsflt_gpr (compare_result, op0, op1);
15295 cmp = (flag_finite_math_only && !flag_trapping_math)
15296 ? gen_tstdflt_gpr (compare_result, op0, op1)
15297 : gen_cmpdflt_gpr (compare_result, op0, op1);
15301 cmp = (flag_finite_math_only && !flag_trapping_math)
15302 ? gen_tsttflt_gpr (compare_result, op0, op1)
15303 : gen_cmptflt_gpr (compare_result, op0, op1);
15307 gcc_unreachable ();
15311 gcc_unreachable ();
15314 /* Synthesize LE and GE from LT/GT || EQ. */
15315 if (code == LE || code == GE || code == LEU || code == GEU)
15321 case LE: code = LT; break;
15322 case GE: code = GT; break;
15323 case LEU: code = LT; break;
15324 case GEU: code = GT; break;
15325 default: gcc_unreachable ();
15328 compare_result2 = gen_reg_rtx (CCFPmode);
15334 cmp = (flag_finite_math_only && !flag_trapping_math)
15335 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15336 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15340 cmp = (flag_finite_math_only && !flag_trapping_math)
15341 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15342 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15346 cmp = (flag_finite_math_only && !flag_trapping_math)
15347 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15348 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15352 gcc_unreachable ();
15356 /* OR them together. */
15357 or_result = gen_reg_rtx (CCFPmode);
15358 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15360 compare_result = or_result;
15365 if (code == NE || code == LTGT)
15375 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15376 CLOBBERs to match cmptf_internal2 pattern. */
15377 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15378 && GET_MODE (op0) == TFmode
15379 && !TARGET_IEEEQUAD
15380 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15381 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15383 gen_rtx_SET (VOIDmode,
15385 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15394 else if (GET_CODE (op1) == UNSPEC
15395 && XINT (op1, 1) == UNSPEC_SP_TEST)
15397 rtx op1b = XVECEXP (op1, 0, 0);
15398 comp_mode = CCEQmode;
15399 compare_result = gen_reg_rtx (CCEQmode);
15401 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15403 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15406 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15407 gen_rtx_COMPARE (comp_mode, op0, op1)));
15410 /* Some kinds of FP comparisons need an OR operation;
15411 under flag_finite_math_only we don't bother. */
15412 if (FLOAT_MODE_P (mode)
15413 && !flag_finite_math_only
15414 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15415 && (code == LE || code == GE
15416 || code == UNEQ || code == LTGT
15417 || code == UNGT || code == UNLT))
15419 enum rtx_code or1, or2;
15420 rtx or1_rtx, or2_rtx, compare2_rtx;
15421 rtx or_result = gen_reg_rtx (CCEQmode);
15425 case LE: or1 = LT; or2 = EQ; break;
15426 case GE: or1 = GT; or2 = EQ; break;
15427 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15428 case LTGT: or1 = LT; or2 = GT; break;
15429 case UNGT: or1 = UNORDERED; or2 = GT; break;
15430 case UNLT: or1 = UNORDERED; or2 = LT; break;
15431 default: gcc_unreachable ();
15433 validate_condition_mode (or1, comp_mode);
15434 validate_condition_mode (or2, comp_mode);
15435 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15436 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15437 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15438 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15440 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15442 compare_result = or_result;
15446 validate_condition_mode (code, GET_MODE (compare_result));
15448 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15452 /* Emit the RTL for an sCOND pattern. */
15455 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15458 enum machine_mode op_mode;
15459 enum rtx_code cond_code;
15460 rtx result = operands[0];
15462 condition_rtx = rs6000_generate_compare (operands[1], mode);
15463 cond_code = GET_CODE (condition_rtx);
15465 op_mode = GET_MODE (XEXP (operands[1], 0));
15466 if (op_mode == VOIDmode)
15467 op_mode = GET_MODE (XEXP (operands[1], 1));
15469 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15471 PUT_MODE (condition_rtx, DImode);
15472 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15473 || cond_code == LTU)
15474 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15475 force_reg (DImode, const1_rtx),
15476 force_reg (DImode, const0_rtx),
15477 XEXP (condition_rtx, 0)));
15479 emit_insn (gen_isel_signed_di (result, condition_rtx,
15480 force_reg (DImode, const1_rtx),
15481 force_reg (DImode, const0_rtx),
15482 XEXP (condition_rtx, 0)));
15486 PUT_MODE (condition_rtx, SImode);
15487 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15488 || cond_code == LTU)
15489 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15490 force_reg (SImode, const1_rtx),
15491 force_reg (SImode, const0_rtx),
15492 XEXP (condition_rtx, 0)));
15494 emit_insn (gen_isel_signed_si (result, condition_rtx,
15495 force_reg (SImode, const1_rtx),
15496 force_reg (SImode, const0_rtx),
15497 XEXP (condition_rtx, 0)));
15502 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15505 enum machine_mode op_mode;
15506 enum rtx_code cond_code;
15507 rtx result = operands[0];
15509 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15511 rs6000_emit_sISEL (mode, operands);
15515 condition_rtx = rs6000_generate_compare (operands[1], mode);
15516 cond_code = GET_CODE (condition_rtx);
15518 if (FLOAT_MODE_P (mode)
15519 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15523 PUT_MODE (condition_rtx, SImode);
15524 t = XEXP (condition_rtx, 0);
15526 gcc_assert (cond_code == NE || cond_code == EQ);
15528 if (cond_code == NE)
15529 emit_insn (gen_e500_flip_gt_bit (t, t));
15531 emit_insn (gen_move_from_CR_gt_bit (result, t));
15535 if (cond_code == NE
15536 || cond_code == GE || cond_code == LE
15537 || cond_code == GEU || cond_code == LEU
15538 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15540 rtx not_result = gen_reg_rtx (CCEQmode);
15541 rtx not_op, rev_cond_rtx;
15542 enum machine_mode cc_mode;
15544 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15546 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15547 SImode, XEXP (condition_rtx, 0), const0_rtx);
15548 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15549 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15550 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15553 op_mode = GET_MODE (XEXP (operands[1], 0));
15554 if (op_mode == VOIDmode)
15555 op_mode = GET_MODE (XEXP (operands[1], 1));
15557 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15559 PUT_MODE (condition_rtx, DImode);
15560 convert_move (result, condition_rtx, 0);
15564 PUT_MODE (condition_rtx, SImode);
15565 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15569 /* Emit a branch of kind CODE to location LOC. */
15572 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15574 rtx condition_rtx, loc_ref;
15576 condition_rtx = rs6000_generate_compare (operands[0], mode);
15577 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15578 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15579 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15580 loc_ref, pc_rtx)));
15583 /* Return the string to output a conditional branch to LABEL, which is
15584 the operand number of the label, or -1 if the branch is really a
15585 conditional return.
15587 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15588 condition code register and its mode specifies what kind of
15589 comparison we made.
15591 REVERSED is nonzero if we should reverse the sense of the comparison.
15593 INSN is the insn. */
15596 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15598 static char string[64];
15599 enum rtx_code code = GET_CODE (op);
15600 rtx cc_reg = XEXP (op, 0);
15601 enum machine_mode mode = GET_MODE (cc_reg);
15602 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15603 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15604 int really_reversed = reversed ^ need_longbranch;
15610 validate_condition_mode (code, mode);
15612 /* Work out which way this really branches. We could use
15613 reverse_condition_maybe_unordered here always but this
15614 makes the resulting assembler clearer. */
15615 if (really_reversed)
15617 /* Reversal of FP compares takes care -- an ordered compare
15618 becomes an unordered compare and vice versa. */
15619 if (mode == CCFPmode)
15620 code = reverse_condition_maybe_unordered (code);
15622 code = reverse_condition (code);
15625 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15627 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15632 /* Opposite of GT. */
15641 gcc_unreachable ();
15647 /* Not all of these are actually distinct opcodes, but
15648 we distinguish them for clarity of the resulting assembler. */
15649 case NE: case LTGT:
15650 ccode = "ne"; break;
15651 case EQ: case UNEQ:
15652 ccode = "eq"; break;
15654 ccode = "ge"; break;
15655 case GT: case GTU: case UNGT:
15656 ccode = "gt"; break;
15658 ccode = "le"; break;
15659 case LT: case LTU: case UNLT:
15660 ccode = "lt"; break;
15661 case UNORDERED: ccode = "un"; break;
15662 case ORDERED: ccode = "nu"; break;
15663 case UNGE: ccode = "nl"; break;
15664 case UNLE: ccode = "ng"; break;
15666 gcc_unreachable ();
15669 /* Maybe we have a guess as to how likely the branch is.
15670 The old mnemonics don't have a way to specify this information. */
15672 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15673 if (note != NULL_RTX)
15675 /* PROB is the difference from 50%. */
15676 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15678 /* Only hint for highly probable/improbable branches on newer
15679 cpus as static prediction overrides processor dynamic
15680 prediction. For older cpus we may as well always hint, but
15681 assume not taken for branches that are very close to 50% as a
15682 mispredicted taken branch is more expensive than a
15683 mispredicted not-taken branch. */
15684 if (rs6000_always_hint
15685 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15686 && br_prob_note_reliable_p (note)))
15688 if (abs (prob) > REG_BR_PROB_BASE / 20
15689 && ((prob > 0) ^ need_longbranch))
15697 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15699 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15701 /* We need to escape any '%' characters in the reg_names string.
15702 Assume they'd only be the first character.... */
15703 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15705 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15709 /* If the branch distance was too far, we may have to use an
15710 unconditional branch to go the distance. */
15711 if (need_longbranch)
15712 s += sprintf (s, ",$+8\n\tb %s", label);
15714 s += sprintf (s, ",%s", label);
15720 /* Return the string to flip the GT bit on a CR. */
15722 output_e500_flip_gt_bit (rtx dst, rtx src)
15724 static char string[64];
15727 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15728 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15731 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15732 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15734 sprintf (string, "crnot %d,%d", a, b);
15738 /* Return insn for VSX or Altivec comparisons. */
15741 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15744 enum machine_mode mode = GET_MODE (op0);
15752 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15758 mask = gen_reg_rtx (mode);
15759 emit_insn (gen_rtx_SET (VOIDmode,
15761 gen_rtx_fmt_ee (code, mode, op0, op1)));
15768 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15769 DMODE is expected destination mode. This is a recursive function. */
15772 rs6000_emit_vector_compare (enum rtx_code rcode,
15774 enum machine_mode dmode)
15777 bool swap_operands = false;
15778 bool try_again = false;
15780 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15781 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15783 /* See if the comparison works as is. */
15784 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15792 swap_operands = true;
15797 swap_operands = true;
15805 /* Invert condition and try again.
15806 e.g., A != B becomes ~(A==B). */
15808 enum rtx_code rev_code;
15809 enum insn_code nor_code;
15812 rev_code = reverse_condition_maybe_unordered (rcode);
15813 if (rev_code == UNKNOWN)
15816 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15817 if (nor_code == CODE_FOR_nothing)
15820 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15824 mask = gen_reg_rtx (dmode);
15825 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15833 /* Try GT/GTU/LT/LTU OR EQ */
15836 enum insn_code ior_code;
15837 enum rtx_code new_code;
15858 gcc_unreachable ();
15861 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15862 if (ior_code == CODE_FOR_nothing)
15865 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15869 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15873 mask = gen_reg_rtx (dmode);
15874 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15892 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15897 /* You only get two chances. */
15901 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15902 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15903 operands for the relation operation COND. */
15906 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15907 rtx cond, rtx cc_op0, rtx cc_op1)
15909 enum machine_mode dest_mode = GET_MODE (dest);
15910 enum rtx_code rcode = GET_CODE (cond);
15911 enum machine_mode cc_mode = CCmode;
15915 bool invert_move = false;
15917 if (VECTOR_UNIT_NONE_P (dest_mode))
15922 /* Swap operands if we can, and fall back to doing the operation as
15923 specified, and doing a NOR to invert the test. */
15929 /* Invert condition and try again.
15930 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15931 invert_move = true;
15932 rcode = reverse_condition_maybe_unordered (rcode);
15933 if (rcode == UNKNOWN)
15937 /* Mark unsigned tests with CCUNSmode. */
15942 cc_mode = CCUNSmode;
15949 /* Get the vector mask for the given relational operations. */
15950 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15958 op_true = op_false;
15962 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15963 emit_insn (gen_rtx_SET (VOIDmode,
15965 gen_rtx_IF_THEN_ELSE (dest_mode,
15972 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15973 operands of the last comparison is nonzero/true, FALSE_COND if it
15974 is zero/false. Return 0 if the hardware has no such operation. */
15977 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15979 enum rtx_code code = GET_CODE (op);
15980 rtx op0 = XEXP (op, 0);
15981 rtx op1 = XEXP (op, 1);
15982 REAL_VALUE_TYPE c1;
15983 enum machine_mode compare_mode = GET_MODE (op0);
15984 enum machine_mode result_mode = GET_MODE (dest);
15986 bool is_against_zero;
15988 /* These modes should always match. */
15989 if (GET_MODE (op1) != compare_mode
15990 /* In the isel case however, we can use a compare immediate, so
15991 op1 may be a small constant. */
15992 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15994 if (GET_MODE (true_cond) != result_mode)
15996 if (GET_MODE (false_cond) != result_mode)
15999 /* First, work out if the hardware can do this at all, or
16000 if it's too slow.... */
16001 if (!FLOAT_MODE_P (compare_mode))
16004 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16007 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16008 && SCALAR_FLOAT_MODE_P (compare_mode))
16011 is_against_zero = op1 == CONST0_RTX (compare_mode);
16013 /* A floating-point subtract might overflow, underflow, or produce
16014 an inexact result, thus changing the floating-point flags, so it
16015 can't be generated if we care about that. It's safe if one side
16016 of the construct is zero, since then no subtract will be
16018 if (SCALAR_FLOAT_MODE_P (compare_mode)
16019 && flag_trapping_math && ! is_against_zero)
16022 /* Eliminate half of the comparisons by switching operands, this
16023 makes the remaining code simpler. */
16024 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16025 || code == LTGT || code == LT || code == UNLE)
16027 code = reverse_condition_maybe_unordered (code);
16029 true_cond = false_cond;
16033 /* UNEQ and LTGT take four instructions for a comparison with zero,
16034 it'll probably be faster to use a branch here too. */
16035 if (code == UNEQ && HONOR_NANS (compare_mode))
16038 if (GET_CODE (op1) == CONST_DOUBLE)
16039 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16041 /* We're going to try to implement comparisons by performing
16042 a subtract, then comparing against zero. Unfortunately,
16043 Inf - Inf is NaN which is not zero, and so if we don't
16044 know that the operand is finite and the comparison
16045 would treat EQ different to UNORDERED, we can't do it. */
16046 if (HONOR_INFINITIES (compare_mode)
16047 && code != GT && code != UNGE
16048 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16049 /* Constructs of the form (a OP b ? a : b) are safe. */
16050 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16051 || (! rtx_equal_p (op0, true_cond)
16052 && ! rtx_equal_p (op1, true_cond))))
16055 /* At this point we know we can use fsel. */
16057 /* Reduce the comparison to a comparison against zero. */
16058 if (! is_against_zero)
16060 temp = gen_reg_rtx (compare_mode);
16061 emit_insn (gen_rtx_SET (VOIDmode, temp,
16062 gen_rtx_MINUS (compare_mode, op0, op1)));
16064 op1 = CONST0_RTX (compare_mode);
16067 /* If we don't care about NaNs we can reduce some of the comparisons
16068 down to faster ones. */
16069 if (! HONOR_NANS (compare_mode))
16075 true_cond = false_cond;
16088 /* Now, reduce everything down to a GE. */
16095 temp = gen_reg_rtx (compare_mode);
16096 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16101 temp = gen_reg_rtx (compare_mode);
16102 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16107 temp = gen_reg_rtx (compare_mode);
16108 emit_insn (gen_rtx_SET (VOIDmode, temp,
16109 gen_rtx_NEG (compare_mode,
16110 gen_rtx_ABS (compare_mode, op0))));
16115 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16116 temp = gen_reg_rtx (result_mode);
16117 emit_insn (gen_rtx_SET (VOIDmode, temp,
16118 gen_rtx_IF_THEN_ELSE (result_mode,
16119 gen_rtx_GE (VOIDmode,
16121 true_cond, false_cond)));
16122 false_cond = true_cond;
16125 temp = gen_reg_rtx (compare_mode);
16126 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16131 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16132 temp = gen_reg_rtx (result_mode);
16133 emit_insn (gen_rtx_SET (VOIDmode, temp,
16134 gen_rtx_IF_THEN_ELSE (result_mode,
16135 gen_rtx_GE (VOIDmode,
16137 true_cond, false_cond)));
16138 true_cond = false_cond;
16141 temp = gen_reg_rtx (compare_mode);
16142 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16147 gcc_unreachable ();
16150 emit_insn (gen_rtx_SET (VOIDmode, dest,
16151 gen_rtx_IF_THEN_ELSE (result_mode,
16152 gen_rtx_GE (VOIDmode,
16154 true_cond, false_cond)));
16158 /* Same as above, but for ints (isel). */
16161 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16163 rtx condition_rtx, cr;
16164 enum machine_mode mode = GET_MODE (dest);
16166 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16169 /* We still have to do the compare, because isel doesn't do a
16170 compare, it just looks at the CRx bits set by a previous compare
16172 condition_rtx = rs6000_generate_compare (op, mode);
16173 cr = XEXP (condition_rtx, 0);
16175 if (mode == SImode)
16177 if (GET_MODE (cr) == CCmode)
16178 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16179 true_cond, false_cond, cr));
16181 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16182 true_cond, false_cond, cr));
16186 if (GET_MODE (cr) == CCmode)
16187 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16188 true_cond, false_cond, cr));
16190 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16191 true_cond, false_cond, cr));
16198 output_isel (rtx *operands)
16200 enum rtx_code code;
16202 code = GET_CODE (operands[1]);
16203 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16205 PUT_CODE (operands[1], reverse_condition (code));
16206 return "isel %0,%3,%2,%j1";
16209 return "isel %0,%2,%3,%j1";
16213 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16215 enum machine_mode mode = GET_MODE (op0);
16219 /* VSX/altivec have direct min/max insns. */
16220 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16222 emit_insn (gen_rtx_SET (VOIDmode,
16224 gen_rtx_fmt_ee (code, mode, op0, op1)));
16228 if (code == SMAX || code == SMIN)
16233 if (code == SMAX || code == UMAX)
16234 target = emit_conditional_move (dest, c, op0, op1, mode,
16235 op0, op1, mode, 0);
16237 target = emit_conditional_move (dest, c, op0, op1, mode,
16238 op1, op0, mode, 0);
16239 gcc_assert (target);
16240 if (target != dest)
16241 emit_move_insn (dest, target);
16244 /* Emit instructions to perform a load-reserved/store-conditional operation.
16245 The operation performed is an atomic
16246 (set M (CODE:MODE M OP))
16247 If not NULL, BEFORE is atomically set to M before the operation, and
16248 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16249 If SYNC_P then a memory barrier is emitted before the operation.
16250 Either OP or M may be wrapped in a NOT operation. */
16253 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16254 rtx m, rtx op, rtx before_param, rtx after_param,
16257 enum machine_mode used_mode;
16258 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16261 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16262 rtx shift = NULL_RTX;
16265 emit_insn (gen_lwsync ());
16269 /* If this is smaller than SImode, we'll have to use SImode with
16271 if (mode == QImode || mode == HImode)
16275 if (MEM_ALIGN (used_m) >= 32)
16278 if (BYTES_BIG_ENDIAN)
16279 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16281 shift = GEN_INT (ishift);
16282 used_m = change_address (used_m, SImode, 0);
16286 rtx addrSI, aligned_addr;
16287 int shift_mask = mode == QImode ? 0x18 : 0x10;
16289 addrSI = gen_lowpart_common (SImode,
16290 force_reg (Pmode, XEXP (used_m, 0)));
16291 addrSI = force_reg (SImode, addrSI);
16292 shift = gen_reg_rtx (SImode);
16294 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16295 GEN_INT (shift_mask)));
16296 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16298 aligned_addr = expand_binop (Pmode, and_optab,
16300 GEN_INT (-4), NULL_RTX,
16301 1, OPTAB_LIB_WIDEN);
16302 used_m = change_address (used_m, SImode, aligned_addr);
16303 set_mem_align (used_m, 32);
16305 /* It's safe to keep the old alias set of USED_M, because
16306 the operation is atomic and only affects the original
16310 if (GET_CODE (op) == NOT)
16312 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16313 oldop = gen_rtx_NOT (SImode, oldop);
16316 oldop = lowpart_subreg (SImode, op, mode);
16322 newop = expand_binop (SImode, and_optab,
16323 oldop, GEN_INT (imask), NULL_RTX,
16324 1, OPTAB_LIB_WIDEN);
16325 emit_insn (gen_ashlsi3 (newop, newop, shift));
16328 case NOT: /* NAND */
16329 newop = expand_binop (SImode, ior_optab,
16330 oldop, GEN_INT (~imask), NULL_RTX,
16331 1, OPTAB_LIB_WIDEN);
16332 emit_insn (gen_rotlsi3 (newop, newop, shift));
16336 newop = expand_binop (SImode, ior_optab,
16337 oldop, GEN_INT (~imask), NULL_RTX,
16338 1, OPTAB_LIB_WIDEN);
16339 emit_insn (gen_rotlsi3 (newop, newop, shift));
16347 newop = expand_binop (SImode, and_optab,
16348 oldop, GEN_INT (imask), NULL_RTX,
16349 1, OPTAB_LIB_WIDEN);
16350 emit_insn (gen_ashlsi3 (newop, newop, shift));
16352 mask = gen_reg_rtx (SImode);
16353 emit_move_insn (mask, GEN_INT (imask));
16354 emit_insn (gen_ashlsi3 (mask, mask, shift));
16357 newop = gen_rtx_PLUS (SImode, m, newop);
16359 newop = gen_rtx_MINUS (SImode, m, newop);
16360 newop = gen_rtx_AND (SImode, newop, mask);
16361 newop = gen_rtx_IOR (SImode, newop,
16362 gen_rtx_AND (SImode,
16363 gen_rtx_NOT (SImode, mask),
16369 gcc_unreachable ();
16373 used_mode = SImode;
16374 before = gen_reg_rtx (used_mode);
16375 after = gen_reg_rtx (used_mode);
16380 before = before_param;
16381 after = after_param;
16383 if (before == NULL_RTX)
16384 before = gen_reg_rtx (used_mode);
16385 if (after == NULL_RTX)
16386 after = gen_reg_rtx (used_mode);
16389 if ((code == PLUS || code == MINUS)
16390 && used_mode != mode)
16391 the_op = op; /* Computed above. */
16392 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16393 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16394 else if (code == NOT)
16395 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16396 gen_rtx_NOT (used_mode, m),
16397 gen_rtx_NOT (used_mode, op));
16399 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16401 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16402 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16403 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16404 gen_rtx_UNSPEC (used_mode,
16405 gen_rtvec (1, the_op),
16407 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16409 if ((code == PLUS || code == MINUS) && used_mode != mode)
16410 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16411 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16413 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16414 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16416 /* Shift and mask the return values properly. */
16417 if (used_mode != mode && before_param)
16419 emit_insn (gen_lshrsi3 (before, before, shift));
16420 convert_move (before_param, before, 1);
16423 if (used_mode != mode && after_param)
16425 emit_insn (gen_lshrsi3 (after, after, shift));
16426 convert_move (after_param, after, 1);
16429 /* The previous sequence will end with a branch that's dependent on
16430 the conditional store, so placing an isync will ensure that no
16431 other instructions (especially, no load or store instructions)
16432 can start before the atomic operation completes. */
16434 emit_insn (gen_isync ());
16437 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16438 COND is true. Mark the jump as unlikely to be taken. */
16441 emit_unlikely_jump (rtx cond, rtx label)
16443 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16446 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16447 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16448 add_reg_note (x, REG_BR_PROB, very_unlikely);
16451 /* A subroutine of the atomic operation splitters. Emit a load-locked
16452 instruction in MODE. */
16455 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16457 rtx (*fn) (rtx, rtx) = NULL;
16458 if (mode == SImode)
16459 fn = gen_load_locked_si;
16460 else if (mode == DImode)
16461 fn = gen_load_locked_di;
16462 emit_insn (fn (reg, mem));
16465 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16466 instruction in MODE. */
16469 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16471 rtx (*fn) (rtx, rtx, rtx) = NULL;
16472 if (mode == SImode)
16473 fn = gen_store_conditional_si;
16474 else if (mode == DImode)
16475 fn = gen_store_conditional_di;
16477 /* Emit sync before stwcx. to address PPC405 Erratum. */
16478 if (PPC405_ERRATUM77)
16479 emit_insn (gen_memory_barrier ());
16481 emit_insn (fn (res, mem, val));
16484 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16485 to perform. MEM is the memory on which to operate. VAL is the second
16486 operand of the binary operator. BEFORE and AFTER are optional locations to
16487 return the value of MEM either before of after the operation. SCRATCH is
16488 a scratch register. */
16491 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16492 rtx before, rtx after, rtx scratch)
16494 enum machine_mode mode = GET_MODE (mem);
16495 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16497 emit_insn (gen_lwsync ());
16499 label = gen_label_rtx ();
16500 emit_label (label);
16501 label = gen_rtx_LABEL_REF (VOIDmode, label);
16503 if (before == NULL_RTX)
16505 emit_load_locked (mode, before, mem);
16508 x = gen_rtx_IOR (mode,
16509 gen_rtx_NOT (mode, before),
16510 gen_rtx_NOT (mode, val));
16511 else if (code == AND)
16512 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16514 x = gen_rtx_fmt_ee (code, mode, before, val);
16516 if (after != NULL_RTX)
16517 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16518 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16520 emit_store_conditional (mode, cond, mem, scratch);
16522 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16523 emit_unlikely_jump (x, label);
16525 emit_insn (gen_isync ());
16528 /* Expand an atomic compare and swap operation. MEM is the memory on which
16529 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16530 value to be stored. SCRATCH is a scratch GPR. */
16533 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16536 enum machine_mode mode = GET_MODE (mem);
16537 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16539 emit_insn (gen_lwsync ());
16541 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16542 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16543 emit_label (XEXP (label1, 0));
16545 emit_load_locked (mode, retval, mem);
16547 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16548 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16550 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16551 emit_unlikely_jump (x, label2);
16553 emit_move_insn (scratch, newval);
16554 emit_store_conditional (mode, cond, mem, scratch);
16556 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16557 emit_unlikely_jump (x, label1);
16559 emit_insn (gen_isync ());
16560 emit_label (XEXP (label2, 0));
16563 /* Expand an atomic test and set operation. MEM is the memory on which
16564 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16567 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16569 enum machine_mode mode = GET_MODE (mem);
16570 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16572 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16573 emit_label (XEXP (label, 0));
16575 emit_load_locked (mode, retval, mem);
16576 emit_move_insn (scratch, val);
16577 emit_store_conditional (mode, cond, mem, scratch);
16579 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16580 emit_unlikely_jump (x, label);
16582 emit_insn (gen_isync ());
16586 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16588 enum machine_mode mode = GET_MODE (mem);
16589 rtx addrSI, align, wdst, shift, mask;
16590 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16591 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16593 /* Shift amount for subword relative to aligned word. */
16594 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16595 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16596 shift = gen_reg_rtx (SImode);
16597 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16598 GEN_INT (shift_mask)));
16599 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16601 /* Shift and mask old value into position within word. */
16602 oldval = convert_modes (SImode, mode, oldval, 1);
16603 oldval = expand_binop (SImode, and_optab,
16604 oldval, GEN_INT (imask), NULL_RTX,
16605 1, OPTAB_LIB_WIDEN);
16606 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16608 /* Shift and mask new value into position within word. */
16609 newval = convert_modes (SImode, mode, newval, 1);
16610 newval = expand_binop (SImode, and_optab,
16611 newval, GEN_INT (imask), NULL_RTX,
16612 1, OPTAB_LIB_WIDEN);
16613 emit_insn (gen_ashlsi3 (newval, newval, shift));
16615 /* Mask for insertion. */
16616 mask = gen_reg_rtx (SImode);
16617 emit_move_insn (mask, GEN_INT (imask));
16618 emit_insn (gen_ashlsi3 (mask, mask, shift));
16620 /* Address of aligned word containing subword. */
16621 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16622 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16623 mem = change_address (mem, SImode, align);
16624 set_mem_align (mem, 32);
16625 MEM_VOLATILE_P (mem) = 1;
16627 wdst = gen_reg_rtx (SImode);
16628 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16629 oldval, newval, mem));
16631 /* Shift the result back. */
16632 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16634 emit_move_insn (dst, gen_lowpart (mode, wdst));
16638 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16639 rtx oldval, rtx newval, rtx mem,
16642 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16644 emit_insn (gen_lwsync ());
16645 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16646 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16647 emit_label (XEXP (label1, 0));
16649 emit_load_locked (SImode, scratch, mem);
16651 /* Mask subword within loaded value for comparison with oldval.
16652 Use UNSPEC_AND to avoid clobber.*/
16653 emit_insn (gen_rtx_SET (SImode, dest,
16654 gen_rtx_UNSPEC (SImode,
16655 gen_rtvec (2, scratch, mask),
16658 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16659 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16661 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16662 emit_unlikely_jump (x, label2);
16664 /* Clear subword within loaded value for insertion of new value. */
16665 emit_insn (gen_rtx_SET (SImode, scratch,
16666 gen_rtx_AND (SImode,
16667 gen_rtx_NOT (SImode, mask), scratch)));
16668 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16669 emit_store_conditional (SImode, cond, mem, scratch);
16671 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16672 emit_unlikely_jump (x, label1);
16674 emit_insn (gen_isync ());
16675 emit_label (XEXP (label2, 0));
16679 /* Emit instructions to move SRC to DST. Called by splitters for
16680 multi-register moves. It will emit at most one instruction for
16681 each register that is accessed; that is, it won't emit li/lis pairs
16682 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16686 rs6000_split_multireg_move (rtx dst, rtx src)
16688 /* The register number of the first register being moved. */
16690 /* The mode that is to be moved. */
16691 enum machine_mode mode;
16692 /* The mode that the move is being done in, and its size. */
16693 enum machine_mode reg_mode;
16695 /* The number of registers that will be moved. */
16698 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16699 mode = GET_MODE (dst);
16700 nregs = hard_regno_nregs[reg][mode];
16701 if (FP_REGNO_P (reg))
16702 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16703 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16704 else if (ALTIVEC_REGNO_P (reg))
16705 reg_mode = V16QImode;
16706 else if (TARGET_E500_DOUBLE && mode == TFmode)
16709 reg_mode = word_mode;
16710 reg_mode_size = GET_MODE_SIZE (reg_mode);
16712 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16714 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16716 /* Move register range backwards, if we might have destructive
16719 for (i = nregs - 1; i >= 0; i--)
16720 emit_insn (gen_rtx_SET (VOIDmode,
16721 simplify_gen_subreg (reg_mode, dst, mode,
16722 i * reg_mode_size),
16723 simplify_gen_subreg (reg_mode, src, mode,
16724 i * reg_mode_size)));
16730 bool used_update = false;
16731 rtx restore_basereg = NULL_RTX;
16733 if (MEM_P (src) && INT_REGNO_P (reg))
16737 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16738 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16741 breg = XEXP (XEXP (src, 0), 0);
16742 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16743 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16744 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16745 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16746 src = replace_equiv_address (src, breg);
16748 else if (! rs6000_offsettable_memref_p (src))
16750 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
16752 rtx basereg = XEXP (XEXP (src, 0), 0);
16755 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
16756 emit_insn (gen_rtx_SET (VOIDmode, ndst,
16757 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
16758 used_update = true;
16761 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16762 XEXP (XEXP (src, 0), 1)));
16763 src = replace_equiv_address (src, basereg);
16767 rtx basereg = gen_rtx_REG (Pmode, reg);
16768 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16769 src = replace_equiv_address (src, basereg);
16773 breg = XEXP (src, 0);
16774 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16775 breg = XEXP (breg, 0);
16777 /* If the base register we are using to address memory is
16778 also a destination reg, then change that register last. */
16780 && REGNO (breg) >= REGNO (dst)
16781 && REGNO (breg) < REGNO (dst) + nregs)
16782 j = REGNO (breg) - REGNO (dst);
16784 else if (MEM_P (dst) && INT_REGNO_P (reg))
16788 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16789 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16792 breg = XEXP (XEXP (dst, 0), 0);
16793 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16794 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16795 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16797 /* We have to update the breg before doing the store.
16798 Use store with update, if available. */
16802 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16803 emit_insn (TARGET_32BIT
16804 ? (TARGET_POWERPC64
16805 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16806 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16807 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16808 used_update = true;
16811 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16812 dst = replace_equiv_address (dst, breg);
16814 else if (!rs6000_offsettable_memref_p (dst)
16815 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
16817 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
16819 rtx basereg = XEXP (XEXP (dst, 0), 0);
16822 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16823 emit_insn (gen_rtx_SET (VOIDmode,
16824 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
16825 used_update = true;
16828 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16829 XEXP (XEXP (dst, 0), 1)));
16830 dst = replace_equiv_address (dst, basereg);
16834 rtx basereg = XEXP (XEXP (dst, 0), 0);
16835 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
16836 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
16838 && REG_P (offsetreg)
16839 && REGNO (basereg) != REGNO (offsetreg));
16840 if (REGNO (basereg) == 0)
16842 rtx tmp = offsetreg;
16843 offsetreg = basereg;
16846 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
16847 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
16848 dst = replace_equiv_address (dst, basereg);
16851 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
16852 gcc_assert (rs6000_offsettable_memref_p (dst));
16855 for (i = 0; i < nregs; i++)
16857 /* Calculate index to next subword. */
16862 /* If compiler already emitted move of first word by
16863 store with update, no need to do anything. */
16864 if (j == 0 && used_update)
16867 emit_insn (gen_rtx_SET (VOIDmode,
16868 simplify_gen_subreg (reg_mode, dst, mode,
16869 j * reg_mode_size),
16870 simplify_gen_subreg (reg_mode, src, mode,
16871 j * reg_mode_size)));
16873 if (restore_basereg != NULL_RTX)
16874 emit_insn (restore_basereg);
16879 /* This page contains routines that are used to determine what the
16880 function prologue and epilogue code will do and write them out. */
16882 /* Return the first fixed-point register that is required to be
16883 saved. 32 if none. */
16886 first_reg_to_save (void)
16890 /* Find lowest numbered live register. */
16891 for (first_reg = 13; first_reg <= 31; first_reg++)
16892 if (df_regs_ever_live_p (first_reg)
16893 && (! call_used_regs[first_reg]
16894 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16895 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16896 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16897 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16902 && crtl->uses_pic_offset_table
16903 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16904 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16910 /* Similar, for FP regs. */
16913 first_fp_reg_to_save (void)
16917 /* Find lowest numbered live register. */
16918 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16919 if (df_regs_ever_live_p (first_reg))
16925 /* Similar, for AltiVec regs. */
16928 first_altivec_reg_to_save (void)
16932 /* Stack frame remains as is unless we are in AltiVec ABI. */
16933 if (! TARGET_ALTIVEC_ABI)
16934 return LAST_ALTIVEC_REGNO + 1;
16936 /* On Darwin, the unwind routines are compiled without
16937 TARGET_ALTIVEC, and use save_world to save/restore the
16938 altivec registers when necessary. */
16939 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16940 && ! TARGET_ALTIVEC)
16941 return FIRST_ALTIVEC_REGNO + 20;
16943 /* Find lowest numbered live register. */
16944 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16945 if (df_regs_ever_live_p (i))
16951 /* Return a 32-bit mask of the AltiVec registers we need to set in
16952 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16953 the 32-bit word is 0. */
16955 static unsigned int
16956 compute_vrsave_mask (void)
16958 unsigned int i, mask = 0;
16960 /* On Darwin, the unwind routines are compiled without
16961 TARGET_ALTIVEC, and use save_world to save/restore the
16962 call-saved altivec registers when necessary. */
16963 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16964 && ! TARGET_ALTIVEC)
16967 /* First, find out if we use _any_ altivec registers. */
16968 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16969 if (df_regs_ever_live_p (i))
16970 mask |= ALTIVEC_REG_BIT (i);
16975 /* Next, remove the argument registers from the set. These must
16976 be in the VRSAVE mask set by the caller, so we don't need to add
16977 them in again. More importantly, the mask we compute here is
16978 used to generate CLOBBERs in the set_vrsave insn, and we do not
16979 wish the argument registers to die. */
16980 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16981 mask &= ~ALTIVEC_REG_BIT (i);
16983 /* Similarly, remove the return value from the set. */
16986 diddle_return_value (is_altivec_return_reg, &yes);
16988 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16994 /* For a very restricted set of circumstances, we can cut down the
16995 size of prologues/epilogues by calling our own save/restore-the-world
16999 compute_save_world_info (rs6000_stack_t *info_ptr)
17001 info_ptr->world_save_p = 1;
17002 info_ptr->world_save_p
17003 = (WORLD_SAVE_P (info_ptr)
17004 && DEFAULT_ABI == ABI_DARWIN
17005 && ! (cfun->calls_setjmp && flag_exceptions)
17006 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17007 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17008 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17009 && info_ptr->cr_save_p);
17011 /* This will not work in conjunction with sibcalls. Make sure there
17012 are none. (This check is expensive, but seldom executed.) */
17013 if (WORLD_SAVE_P (info_ptr))
17016 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17017 if ( GET_CODE (insn) == CALL_INSN
17018 && SIBLING_CALL_P (insn))
17020 info_ptr->world_save_p = 0;
17025 if (WORLD_SAVE_P (info_ptr))
17027 /* Even if we're not touching VRsave, make sure there's room on the
17028 stack for it, if it looks like we're calling SAVE_WORLD, which
17029 will attempt to save it. */
17030 info_ptr->vrsave_size = 4;
17032 /* If we are going to save the world, we need to save the link register too. */
17033 info_ptr->lr_save_p = 1;
17035 /* "Save" the VRsave register too if we're saving the world. */
17036 if (info_ptr->vrsave_mask == 0)
17037 info_ptr->vrsave_mask = compute_vrsave_mask ();
17039 /* Because the Darwin register save/restore routines only handle
17040 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17042 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17043 && (info_ptr->first_altivec_reg_save
17044 >= FIRST_SAVED_ALTIVEC_REGNO));
17051 is_altivec_return_reg (rtx reg, void *xyes)
17053 bool *yes = (bool *) xyes;
17054 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17059 /* Calculate the stack information for the current function. This is
17060 complicated by having two separate calling sequences, the AIX calling
17061 sequence and the V.4 calling sequence.
17063 AIX (and Darwin/Mac OS X) stack frames look like:
17065 SP----> +---------------------------------------+
17066 | back chain to caller | 0 0
17067 +---------------------------------------+
17068 | saved CR | 4 8 (8-11)
17069 +---------------------------------------+
17071 +---------------------------------------+
17072 | reserved for compilers | 12 24
17073 +---------------------------------------+
17074 | reserved for binders | 16 32
17075 +---------------------------------------+
17076 | saved TOC pointer | 20 40
17077 +---------------------------------------+
17078 | Parameter save area (P) | 24 48
17079 +---------------------------------------+
17080 | Alloca space (A) | 24+P etc.
17081 +---------------------------------------+
17082 | Local variable space (L) | 24+P+A
17083 +---------------------------------------+
17084 | Float/int conversion temporary (X) | 24+P+A+L
17085 +---------------------------------------+
17086 | Save area for AltiVec registers (W) | 24+P+A+L+X
17087 +---------------------------------------+
17088 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17089 +---------------------------------------+
17090 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17091 +---------------------------------------+
17092 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17093 +---------------------------------------+
17094 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17095 +---------------------------------------+
17096 old SP->| back chain to caller's caller |
17097 +---------------------------------------+
17099 The required alignment for AIX configurations is two words (i.e., 8
17103 V.4 stack frames look like:
17105 SP----> +---------------------------------------+
17106 | back chain to caller | 0
17107 +---------------------------------------+
17108 | caller's saved LR | 4
17109 +---------------------------------------+
17110 | Parameter save area (P) | 8
17111 +---------------------------------------+
17112 | Alloca space (A) | 8+P
17113 +---------------------------------------+
17114 | Varargs save area (V) | 8+P+A
17115 +---------------------------------------+
17116 | Local variable space (L) | 8+P+A+V
17117 +---------------------------------------+
17118 | Float/int conversion temporary (X) | 8+P+A+V+L
17119 +---------------------------------------+
17120 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17121 +---------------------------------------+
17122 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17123 +---------------------------------------+
17124 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17125 +---------------------------------------+
17126 | SPE: area for 64-bit GP registers |
17127 +---------------------------------------+
17128 | SPE alignment padding |
17129 +---------------------------------------+
17130 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17131 +---------------------------------------+
17132 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17133 +---------------------------------------+
17134 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17135 +---------------------------------------+
17136 old SP->| back chain to caller's caller |
17137 +---------------------------------------+
17139 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17140 given. (But note below and in sysv4.h that we require only 8 and
17141 may round up the size of our stack frame anyways. The historical
17142 reason is early versions of powerpc-linux which didn't properly
17143 align the stack at program startup. A happy side-effect is that
17144 -mno-eabi libraries can be used with -meabi programs.)
17146 The EABI configuration defaults to the V.4 layout. However,
17147 the stack alignment requirements may differ. If -mno-eabi is not
17148 given, the required stack alignment is 8 bytes; if -mno-eabi is
17149 given, the required alignment is 16 bytes. (But see V.4 comment
17152 #ifndef ABI_STACK_BOUNDARY
17153 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17156 static rs6000_stack_t *
17157 rs6000_stack_info (void)
17159 static rs6000_stack_t info;
17160 rs6000_stack_t *info_ptr = &info;
17161 int reg_size = TARGET_32BIT ? 4 : 8;
17165 HOST_WIDE_INT non_fixed_size;
17167 memset (&info, 0, sizeof (info));
17171 /* Cache value so we don't rescan instruction chain over and over. */
17172 if (cfun->machine->insn_chain_scanned_p == 0)
17173 cfun->machine->insn_chain_scanned_p
17174 = spe_func_has_64bit_regs_p () + 1;
17175 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17178 /* Select which calling sequence. */
17179 info_ptr->abi = DEFAULT_ABI;
17181 /* Calculate which registers need to be saved & save area size. */
17182 info_ptr->first_gp_reg_save = first_reg_to_save ();
17183 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17184 even if it currently looks like we won't. Reload may need it to
17185 get at a constant; if so, it will have already created a constant
17186 pool entry for it. */
17187 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17188 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17189 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17190 && crtl->uses_const_pool
17191 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17192 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17194 first_gp = info_ptr->first_gp_reg_save;
17196 info_ptr->gp_size = reg_size * (32 - first_gp);
17198 /* For the SPE, we have an additional upper 32-bits on each GPR.
17199 Ideally we should save the entire 64-bits only when the upper
17200 half is used in SIMD instructions. Since we only record
17201 registers live (not the size they are used in), this proves
17202 difficult because we'd have to traverse the instruction chain at
17203 the right time, taking reload into account. This is a real pain,
17204 so we opt to save the GPRs in 64-bits always if but one register
17205 gets used in 64-bits. Otherwise, all the registers in the frame
17206 get saved in 32-bits.
17208 So... since when we save all GPRs (except the SP) in 64-bits, the
17209 traditional GP save area will be empty. */
17210 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17211 info_ptr->gp_size = 0;
17213 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17214 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17216 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17217 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17218 - info_ptr->first_altivec_reg_save);
17220 /* Does this function call anything? */
17221 info_ptr->calls_p = (! current_function_is_leaf
17222 || cfun->machine->ra_needs_full_frame);
17224 /* Determine if we need to save the link register. */
17225 if ((DEFAULT_ABI == ABI_AIX
17227 && !TARGET_PROFILE_KERNEL)
17228 #ifdef TARGET_RELOCATABLE
17229 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17231 || (info_ptr->first_fp_reg_save != 64
17232 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17233 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17234 || info_ptr->calls_p
17235 || rs6000_ra_ever_killed ())
17237 info_ptr->lr_save_p = 1;
17238 df_set_regs_ever_live (LR_REGNO, true);
17241 /* Determine if we need to save the condition code registers. */
17242 if (df_regs_ever_live_p (CR2_REGNO)
17243 || df_regs_ever_live_p (CR3_REGNO)
17244 || df_regs_ever_live_p (CR4_REGNO))
17246 info_ptr->cr_save_p = 1;
17247 if (DEFAULT_ABI == ABI_V4)
17248 info_ptr->cr_size = reg_size;
17251 /* If the current function calls __builtin_eh_return, then we need
17252 to allocate stack space for registers that will hold data for
17253 the exception handler. */
17254 if (crtl->calls_eh_return)
17257 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17260 /* SPE saves EH registers in 64-bits. */
17261 ehrd_size = i * (TARGET_SPE_ABI
17262 && info_ptr->spe_64bit_regs_used != 0
17263 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17268 /* Determine various sizes. */
17269 info_ptr->reg_size = reg_size;
17270 info_ptr->fixed_size = RS6000_SAVE_AREA;
17271 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17272 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17273 TARGET_ALTIVEC ? 16 : 8);
17274 if (FRAME_GROWS_DOWNWARD)
17275 info_ptr->vars_size
17276 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17277 + info_ptr->parm_size,
17278 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17279 - (info_ptr->fixed_size + info_ptr->vars_size
17280 + info_ptr->parm_size);
17282 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17283 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17285 info_ptr->spe_gp_size = 0;
17287 if (TARGET_ALTIVEC_ABI)
17288 info_ptr->vrsave_mask = compute_vrsave_mask ();
17290 info_ptr->vrsave_mask = 0;
17292 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17293 info_ptr->vrsave_size = 4;
17295 info_ptr->vrsave_size = 0;
17297 compute_save_world_info (info_ptr);
17299 /* Calculate the offsets. */
17300 switch (DEFAULT_ABI)
17304 gcc_unreachable ();
17308 info_ptr->fp_save_offset = - info_ptr->fp_size;
17309 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17311 if (TARGET_ALTIVEC_ABI)
17313 info_ptr->vrsave_save_offset
17314 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17316 /* Align stack so vector save area is on a quadword boundary.
17317 The padding goes above the vectors. */
17318 if (info_ptr->altivec_size != 0)
17319 info_ptr->altivec_padding_size
17320 = info_ptr->vrsave_save_offset & 0xF;
17322 info_ptr->altivec_padding_size = 0;
17324 info_ptr->altivec_save_offset
17325 = info_ptr->vrsave_save_offset
17326 - info_ptr->altivec_padding_size
17327 - info_ptr->altivec_size;
17328 gcc_assert (info_ptr->altivec_size == 0
17329 || info_ptr->altivec_save_offset % 16 == 0);
17331 /* Adjust for AltiVec case. */
17332 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17335 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17336 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17337 info_ptr->lr_save_offset = 2*reg_size;
17341 info_ptr->fp_save_offset = - info_ptr->fp_size;
17342 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17343 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17345 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17347 /* Align stack so SPE GPR save area is aligned on a
17348 double-word boundary. */
17349 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17350 info_ptr->spe_padding_size
17351 = 8 - (-info_ptr->cr_save_offset % 8);
17353 info_ptr->spe_padding_size = 0;
17355 info_ptr->spe_gp_save_offset
17356 = info_ptr->cr_save_offset
17357 - info_ptr->spe_padding_size
17358 - info_ptr->spe_gp_size;
17360 /* Adjust for SPE case. */
17361 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17363 else if (TARGET_ALTIVEC_ABI)
17365 info_ptr->vrsave_save_offset
17366 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17368 /* Align stack so vector save area is on a quadword boundary. */
17369 if (info_ptr->altivec_size != 0)
17370 info_ptr->altivec_padding_size
17371 = 16 - (-info_ptr->vrsave_save_offset % 16);
17373 info_ptr->altivec_padding_size = 0;
17375 info_ptr->altivec_save_offset
17376 = info_ptr->vrsave_save_offset
17377 - info_ptr->altivec_padding_size
17378 - info_ptr->altivec_size;
17380 /* Adjust for AltiVec case. */
17381 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17384 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17385 info_ptr->ehrd_offset -= ehrd_size;
17386 info_ptr->lr_save_offset = reg_size;
17390 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17391 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17392 + info_ptr->gp_size
17393 + info_ptr->altivec_size
17394 + info_ptr->altivec_padding_size
17395 + info_ptr->spe_gp_size
17396 + info_ptr->spe_padding_size
17398 + info_ptr->cr_size
17399 + info_ptr->vrsave_size,
17402 non_fixed_size = (info_ptr->vars_size
17403 + info_ptr->parm_size
17404 + info_ptr->save_size);
17406 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17407 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17409 /* Determine if we need to allocate any stack frame:
17411 For AIX we need to push the stack if a frame pointer is needed
17412 (because the stack might be dynamically adjusted), if we are
17413 debugging, if we make calls, or if the sum of fp_save, gp_save,
17414 and local variables are more than the space needed to save all
17415 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17416 + 18*8 = 288 (GPR13 reserved).
17418 For V.4 we don't have the stack cushion that AIX uses, but assume
17419 that the debugger can handle stackless frames. */
17421 if (info_ptr->calls_p)
17422 info_ptr->push_p = 1;
17424 else if (DEFAULT_ABI == ABI_V4)
17425 info_ptr->push_p = non_fixed_size != 0;
17427 else if (frame_pointer_needed)
17428 info_ptr->push_p = 1;
17430 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17431 info_ptr->push_p = 1;
17434 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17436 /* Zero offsets if we're not saving those registers. */
17437 if (info_ptr->fp_size == 0)
17438 info_ptr->fp_save_offset = 0;
17440 if (info_ptr->gp_size == 0)
17441 info_ptr->gp_save_offset = 0;
17443 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17444 info_ptr->altivec_save_offset = 0;
17446 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17447 info_ptr->vrsave_save_offset = 0;
17449 if (! TARGET_SPE_ABI
17450 || info_ptr->spe_64bit_regs_used == 0
17451 || info_ptr->spe_gp_size == 0)
17452 info_ptr->spe_gp_save_offset = 0;
17454 if (! info_ptr->lr_save_p)
17455 info_ptr->lr_save_offset = 0;
17457 if (! info_ptr->cr_save_p)
17458 info_ptr->cr_save_offset = 0;
17463 /* Return true if the current function uses any GPRs in 64-bit SIMD
17467 spe_func_has_64bit_regs_p (void)
17471 /* Functions that save and restore all the call-saved registers will
17472 need to save/restore the registers in 64-bits. */
17473 if (crtl->calls_eh_return
17474 || cfun->calls_setjmp
17475 || crtl->has_nonlocal_goto)
17478 insns = get_insns ();
17480 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17486 /* FIXME: This should be implemented with attributes...
17488 (set_attr "spe64" "true")....then,
17489 if (get_spe64(insn)) return true;
17491 It's the only reliable way to do the stuff below. */
17493 i = PATTERN (insn);
17494 if (GET_CODE (i) == SET)
17496 enum machine_mode mode = GET_MODE (SET_SRC (i));
17498 if (SPE_VECTOR_MODE (mode))
17500 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17510 debug_stack_info (rs6000_stack_t *info)
17512 const char *abi_string;
17515 info = rs6000_stack_info ();
17517 fprintf (stderr, "\nStack information for function %s:\n",
17518 ((current_function_decl && DECL_NAME (current_function_decl))
17519 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17524 default: abi_string = "Unknown"; break;
17525 case ABI_NONE: abi_string = "NONE"; break;
17526 case ABI_AIX: abi_string = "AIX"; break;
17527 case ABI_DARWIN: abi_string = "Darwin"; break;
17528 case ABI_V4: abi_string = "V.4"; break;
17531 fprintf (stderr, "\tABI = %5s\n", abi_string);
17533 if (TARGET_ALTIVEC_ABI)
17534 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17536 if (TARGET_SPE_ABI)
17537 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17539 if (info->first_gp_reg_save != 32)
17540 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17542 if (info->first_fp_reg_save != 64)
17543 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17545 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17546 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17547 info->first_altivec_reg_save);
17549 if (info->lr_save_p)
17550 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17552 if (info->cr_save_p)
17553 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17555 if (info->vrsave_mask)
17556 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17559 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17562 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17564 if (info->gp_save_offset)
17565 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17567 if (info->fp_save_offset)
17568 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17570 if (info->altivec_save_offset)
17571 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17572 info->altivec_save_offset);
17574 if (info->spe_gp_save_offset)
17575 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17576 info->spe_gp_save_offset);
17578 if (info->vrsave_save_offset)
17579 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17580 info->vrsave_save_offset);
17582 if (info->lr_save_offset)
17583 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17585 if (info->cr_save_offset)
17586 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17588 if (info->varargs_save_offset)
17589 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17591 if (info->total_size)
17592 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17595 if (info->vars_size)
17596 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17599 if (info->parm_size)
17600 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17602 if (info->fixed_size)
17603 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17606 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17608 if (info->spe_gp_size)
17609 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17612 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17614 if (info->altivec_size)
17615 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17617 if (info->vrsave_size)
17618 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17620 if (info->altivec_padding_size)
17621 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17622 info->altivec_padding_size);
17624 if (info->spe_padding_size)
17625 fprintf (stderr, "\tspe_padding_size = %5d\n",
17626 info->spe_padding_size);
17629 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17631 if (info->save_size)
17632 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17634 if (info->reg_size != 4)
17635 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17637 fprintf (stderr, "\n");
17641 rs6000_return_addr (int count, rtx frame)
17643 /* Currently we don't optimize very well between prolog and body
17644 code and for PIC code the code can be actually quite bad, so
17645 don't try to be too clever here. */
17646 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17648 cfun->machine->ra_needs_full_frame = 1;
17655 plus_constant (copy_to_reg
17656 (gen_rtx_MEM (Pmode,
17657 memory_address (Pmode, frame))),
17658 RETURN_ADDRESS_OFFSET)));
17661 cfun->machine->ra_need_lr = 1;
17662 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17665 /* Say whether a function is a candidate for sibcall handling or not.
17666 We do not allow indirect calls to be optimized into sibling calls.
17667 Also, we can't do it if there are any vector parameters; there's
17668 nowhere to put the VRsave code so it works; note that functions with
17669 vector parameters are required to have a prototype, so the argument
17670 type info must be available here. (The tail recursion case can work
17671 with vector parameters, but there's no way to distinguish here.) */
17673 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17678 if (TARGET_ALTIVEC_VRSAVE)
17680 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17681 type; type = TREE_CHAIN (type))
17683 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17687 if (DEFAULT_ABI == ABI_DARWIN
17688 || ((*targetm.binds_local_p) (decl)
17689 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17691 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17693 if (!lookup_attribute ("longcall", attr_list)
17694 || lookup_attribute ("shortcall", attr_list))
17701 /* NULL if INSN insn is valid within a low-overhead loop.
17702 Otherwise return why doloop cannot be applied.
17703 PowerPC uses the COUNT register for branch on table instructions. */
17705 static const char *
17706 rs6000_invalid_within_doloop (const_rtx insn)
17709 return "Function call in the loop.";
17712 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17713 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17714 return "Computed branch in the loop.";
17720 rs6000_ra_ever_killed (void)
17726 if (cfun->is_thunk)
17729 /* regs_ever_live has LR marked as used if any sibcalls are present,
17730 but this should not force saving and restoring in the
17731 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17732 clobbers LR, so that is inappropriate. */
17734 /* Also, the prologue can generate a store into LR that
17735 doesn't really count, like this:
17738 bcl to set PIC register
17742 When we're called from the epilogue, we need to avoid counting
17743 this as a store. */
17745 push_topmost_sequence ();
17746 top = get_insns ();
17747 pop_topmost_sequence ();
17748 reg = gen_rtx_REG (Pmode, LR_REGNO);
17750 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17756 if (!SIBLING_CALL_P (insn))
17759 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17761 else if (set_of (reg, insn) != NULL_RTX
17762 && !prologue_epilogue_contains (insn))
17769 /* Emit instructions needed to load the TOC register.
17770 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17771 a constant pool; or for SVR4 -fpic. */
17774 rs6000_emit_load_toc_table (int fromprolog)
17777 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17779 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17782 rtx lab, tmp1, tmp2, got;
17784 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17785 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17787 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17789 got = rs6000_got_sym ();
17790 tmp1 = tmp2 = dest;
17793 tmp1 = gen_reg_rtx (Pmode);
17794 tmp2 = gen_reg_rtx (Pmode);
17796 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17797 emit_move_insn (tmp1,
17798 gen_rtx_REG (Pmode, LR_REGNO));
17799 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17800 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17802 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17804 emit_insn (gen_load_toc_v4_pic_si ());
17805 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17807 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17810 rtx temp0 = (fromprolog
17811 ? gen_rtx_REG (Pmode, 0)
17812 : gen_reg_rtx (Pmode));
17818 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17819 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17821 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17822 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17824 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17825 emit_move_insn (dest,
17826 gen_rtx_REG (Pmode, LR_REGNO));
17827 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17833 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17834 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17835 emit_move_insn (dest,
17836 gen_rtx_REG (Pmode, LR_REGNO));
17837 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17839 emit_insn (gen_addsi3 (dest, temp0, dest));
17841 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17843 /* This is for AIX code running in non-PIC ELF32. */
17846 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17847 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17849 emit_insn (gen_elf_high (dest, realsym));
17850 emit_insn (gen_elf_low (dest, dest, realsym));
17854 gcc_assert (DEFAULT_ABI == ABI_AIX);
17857 emit_insn (gen_load_toc_aix_si (dest));
17859 emit_insn (gen_load_toc_aix_di (dest));
17863 /* Emit instructions to restore the link register after determining where
17864 its value has been stored. */
17867 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17869 rs6000_stack_t *info = rs6000_stack_info ();
17872 operands[0] = source;
17873 operands[1] = scratch;
17875 if (info->lr_save_p)
17877 rtx frame_rtx = stack_pointer_rtx;
17878 HOST_WIDE_INT sp_offset = 0;
17881 if (frame_pointer_needed
17882 || cfun->calls_alloca
17883 || info->total_size > 32767)
17885 tmp = gen_frame_mem (Pmode, frame_rtx);
17886 emit_move_insn (operands[1], tmp);
17887 frame_rtx = operands[1];
17889 else if (info->push_p)
17890 sp_offset = info->total_size;
17892 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17893 tmp = gen_frame_mem (Pmode, tmp);
17894 emit_move_insn (tmp, operands[0]);
17897 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17900 static GTY(()) alias_set_type set = -1;
17903 get_TOC_alias_set (void)
17906 set = new_alias_set ();
17910 /* This returns nonzero if the current function uses the TOC. This is
17911 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17912 is generated by the ABI_V4 load_toc_* patterns. */
17919 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17922 rtx pat = PATTERN (insn);
17925 if (GET_CODE (pat) == PARALLEL)
17926 for (i = 0; i < XVECLEN (pat, 0); i++)
17928 rtx sub = XVECEXP (pat, 0, i);
17929 if (GET_CODE (sub) == USE)
17931 sub = XEXP (sub, 0);
17932 if (GET_CODE (sub) == UNSPEC
17933 && XINT (sub, 1) == UNSPEC_TOC)
17943 create_TOC_reference (rtx symbol)
17945 if (TARGET_DEBUG_ADDR)
17947 if (GET_CODE (symbol) == SYMBOL_REF)
17948 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17952 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17953 GET_RTX_NAME (GET_CODE (symbol)));
17954 debug_rtx (symbol);
17958 if (!can_create_pseudo_p ())
17959 df_set_regs_ever_live (TOC_REGISTER, true);
17960 return gen_rtx_PLUS (Pmode,
17961 gen_rtx_REG (Pmode, TOC_REGISTER),
17962 gen_rtx_CONST (Pmode,
17963 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17966 /* Issue assembly directives that create a reference to the given DWARF
17967 FRAME_TABLE_LABEL from the current function section. */
17969 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17971 fprintf (asm_out_file, "\t.ref %s\n",
17972 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17975 /* If _Unwind_* has been called from within the same module,
17976 toc register is not guaranteed to be saved to 40(1) on function
17977 entry. Save it there in that case. */
17980 rs6000_aix_emit_builtin_unwind_init (void)
17983 rtx stack_top = gen_reg_rtx (Pmode);
17984 rtx opcode_addr = gen_reg_rtx (Pmode);
17985 rtx opcode = gen_reg_rtx (SImode);
17986 rtx tocompare = gen_reg_rtx (SImode);
17987 rtx no_toc_save_needed = gen_label_rtx ();
17989 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17990 emit_move_insn (stack_top, mem);
17992 mem = gen_frame_mem (Pmode,
17993 gen_rtx_PLUS (Pmode, stack_top,
17994 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17995 emit_move_insn (opcode_addr, mem);
17996 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17997 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17998 : 0xE8410028, SImode));
18000 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18001 SImode, NULL_RTX, NULL_RTX,
18002 no_toc_save_needed, -1);
18004 mem = gen_frame_mem (Pmode,
18005 gen_rtx_PLUS (Pmode, stack_top,
18006 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18007 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18008 emit_label (no_toc_save_needed);
18011 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18012 and the change to the stack pointer. */
18015 rs6000_emit_stack_tie (void)
18017 rtx mem = gen_frame_mem (BLKmode,
18018 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18020 emit_insn (gen_stack_tie (mem));
18023 /* Emit the correct code for allocating stack space, as insns.
18024 If COPY_R12, make sure a copy of the old frame is left in r12.
18025 If COPY_R11, make sure a copy of the old frame is left in r11,
18026 in preference to r12 if COPY_R12.
18027 The generated code may use hard register 0 as a temporary. */
18030 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
18033 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18034 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18035 rtx todec = gen_int_mode (-size, Pmode);
18038 if (INTVAL (todec) != -size)
18040 warning (0, "stack frame too large");
18041 emit_insn (gen_trap ());
18045 if (crtl->limit_stack)
18047 if (REG_P (stack_limit_rtx)
18048 && REGNO (stack_limit_rtx) > 1
18049 && REGNO (stack_limit_rtx) <= 31)
18051 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18052 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18055 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18057 && DEFAULT_ABI == ABI_V4)
18059 rtx toload = gen_rtx_CONST (VOIDmode,
18060 gen_rtx_PLUS (Pmode,
18064 emit_insn (gen_elf_high (tmp_reg, toload));
18065 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18066 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18070 warning (0, "stack limit expression is not supported");
18073 if (copy_r12 || copy_r11)
18074 emit_move_insn (copy_r11
18075 ? gen_rtx_REG (Pmode, 11)
18076 : gen_rtx_REG (Pmode, 12),
18081 /* Need a note here so that try_split doesn't get confused. */
18082 if (get_last_insn () == NULL_RTX)
18083 emit_note (NOTE_INSN_DELETED);
18084 insn = emit_move_insn (tmp_reg, todec);
18085 try_split (PATTERN (insn), insn, 0);
18089 insn = emit_insn (TARGET_32BIT
18090 ? gen_movsi_update_stack (stack_reg, stack_reg,
18092 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18093 todec, stack_reg));
18094 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18095 it now and set the alias set/attributes. The above gen_*_update
18096 calls will generate a PARALLEL with the MEM set being the first
18098 par = PATTERN (insn);
18099 gcc_assert (GET_CODE (par) == PARALLEL);
18100 set = XVECEXP (par, 0, 0);
18101 gcc_assert (GET_CODE (set) == SET);
18102 mem = SET_DEST (set);
18103 gcc_assert (MEM_P (mem));
18104 MEM_NOTRAP_P (mem) = 1;
18105 set_mem_alias_set (mem, get_frame_alias_set ());
18107 RTX_FRAME_RELATED_P (insn) = 1;
18108 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18109 gen_rtx_SET (VOIDmode, stack_reg,
18110 gen_rtx_PLUS (Pmode, stack_reg,
18111 GEN_INT (-size))));
18114 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18115 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18116 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18117 deduce these equivalences by itself so it wasn't necessary to hold
18118 its hand so much. */
18121 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18122 rtx reg2, rtx rreg)
18126 /* copy_rtx will not make unique copies of registers, so we need to
18127 ensure we don't have unwanted sharing here. */
18129 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18132 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18134 real = copy_rtx (PATTERN (insn));
18136 if (reg2 != NULL_RTX)
18137 real = replace_rtx (real, reg2, rreg);
18139 real = replace_rtx (real, reg,
18140 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18141 STACK_POINTER_REGNUM),
18144 /* We expect that 'real' is either a SET or a PARALLEL containing
18145 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18146 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18148 if (GET_CODE (real) == SET)
18152 temp = simplify_rtx (SET_SRC (set));
18154 SET_SRC (set) = temp;
18155 temp = simplify_rtx (SET_DEST (set));
18157 SET_DEST (set) = temp;
18158 if (GET_CODE (SET_DEST (set)) == MEM)
18160 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18162 XEXP (SET_DEST (set), 0) = temp;
18169 gcc_assert (GET_CODE (real) == PARALLEL);
18170 for (i = 0; i < XVECLEN (real, 0); i++)
18171 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18173 rtx set = XVECEXP (real, 0, i);
18175 temp = simplify_rtx (SET_SRC (set));
18177 SET_SRC (set) = temp;
18178 temp = simplify_rtx (SET_DEST (set));
18180 SET_DEST (set) = temp;
18181 if (GET_CODE (SET_DEST (set)) == MEM)
18183 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18185 XEXP (SET_DEST (set), 0) = temp;
18187 RTX_FRAME_RELATED_P (set) = 1;
18191 RTX_FRAME_RELATED_P (insn) = 1;
18192 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18195 /* Returns an insn that has a vrsave set operation with the
18196 appropriate CLOBBERs. */
18199 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18202 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18203 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18206 = gen_rtx_SET (VOIDmode,
18208 gen_rtx_UNSPEC_VOLATILE (SImode,
18209 gen_rtvec (2, reg, vrsave),
18210 UNSPECV_SET_VRSAVE));
18214 /* We need to clobber the registers in the mask so the scheduler
18215 does not move sets to VRSAVE before sets of AltiVec registers.
18217 However, if the function receives nonlocal gotos, reload will set
18218 all call saved registers live. We will end up with:
18220 (set (reg 999) (mem))
18221 (parallel [ (set (reg vrsave) (unspec blah))
18222 (clobber (reg 999))])
18224 The clobber will cause the store into reg 999 to be dead, and
18225 flow will attempt to delete an epilogue insn. In this case, we
18226 need an unspec use/set of the register. */
18228 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18229 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18231 if (!epiloguep || call_used_regs [i])
18232 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18233 gen_rtx_REG (V4SImode, i));
18236 rtx reg = gen_rtx_REG (V4SImode, i);
18239 = gen_rtx_SET (VOIDmode,
18241 gen_rtx_UNSPEC (V4SImode,
18242 gen_rtvec (1, reg), 27));
18246 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18248 for (i = 0; i < nclobs; ++i)
18249 XVECEXP (insn, 0, i) = clobs[i];
18254 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18255 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18258 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18259 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18261 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18262 rtx replacea, replaceb;
18264 int_rtx = GEN_INT (offset);
18266 /* Some cases that need register indexed addressing. */
18267 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18268 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18269 || (TARGET_E500_DOUBLE && mode == DFmode)
18271 && SPE_VECTOR_MODE (mode)
18272 && !SPE_CONST_OFFSET_OK (offset)))
18274 /* Whomever calls us must make sure r11 is available in the
18275 flow path of instructions in the prologue. */
18276 offset_rtx = gen_rtx_REG (Pmode, 11);
18277 emit_move_insn (offset_rtx, int_rtx);
18279 replacea = offset_rtx;
18280 replaceb = int_rtx;
18284 offset_rtx = int_rtx;
18285 replacea = NULL_RTX;
18286 replaceb = NULL_RTX;
18289 reg = gen_rtx_REG (mode, regno);
18290 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18291 mem = gen_frame_mem (mode, addr);
18293 insn = emit_move_insn (mem, reg);
18295 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18298 /* Emit an offset memory reference suitable for a frame store, while
18299 converting to a valid addressing mode. */
18302 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18304 rtx int_rtx, offset_rtx;
18306 int_rtx = GEN_INT (offset);
18308 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18309 || (TARGET_E500_DOUBLE && mode == DFmode))
18311 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18312 emit_move_insn (offset_rtx, int_rtx);
18315 offset_rtx = int_rtx;
18317 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18320 /* Look for user-defined global regs. We should not save and restore these,
18321 and cannot use stmw/lmw if there are any in its range. */
18324 no_global_regs_above (int first, bool gpr)
18327 int last = gpr ? 32 : 64;
18328 for (i = first; i < last; i++)
18329 if (global_regs[i])
18334 #ifndef TARGET_FIX_AND_CONTINUE
18335 #define TARGET_FIX_AND_CONTINUE 0
18338 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18339 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18340 #define LAST_SAVRES_REGISTER 31
18341 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18343 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18345 /* Temporary holding space for an out-of-line register save/restore
18347 static char savres_routine_name[30];
18349 /* Return the name for an out-of-line register save/restore routine.
18350 We are saving/restoring GPRs if GPR is true. */
18353 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18354 bool savep, bool gpr, bool lr)
18356 const char *prefix = "";
18357 const char *suffix = "";
18359 /* Different targets are supposed to define
18360 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18361 routine name could be defined with:
18363 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18365 This is a nice idea in practice, but in reality, things are
18366 complicated in several ways:
18368 - ELF targets have save/restore routines for GPRs.
18370 - SPE targets use different prefixes for 32/64-bit registers, and
18371 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18373 - PPC64 ELF targets have routines for save/restore of GPRs that
18374 differ in what they do with the link register, so having a set
18375 prefix doesn't work. (We only use one of the save routines at
18376 the moment, though.)
18378 - PPC32 elf targets have "exit" versions of the restore routines
18379 that restore the link register and can save some extra space.
18380 These require an extra suffix. (There are also "tail" versions
18381 of the restore routines and "GOT" versions of the save routines,
18382 but we don't generate those at present. Same problems apply,
18385 We deal with all this by synthesizing our own prefix/suffix and
18386 using that for the simple sprintf call shown above. */
18389 /* No floating point saves on the SPE. */
18393 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18395 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18400 else if (DEFAULT_ABI == ABI_V4)
18406 prefix = savep ? "_savegpr_" : "_restgpr_";
18408 prefix = savep ? "_savefpr_" : "_restfpr_";
18413 else if (DEFAULT_ABI == ABI_AIX)
18415 #ifndef POWERPC_LINUX
18416 /* No out-of-line save/restore routines for GPRs on AIX. */
18417 gcc_assert (!TARGET_AIX || !gpr);
18423 ? (lr ? "_savegpr0_" : "_savegpr1_")
18424 : (lr ? "_restgpr0_" : "_restgpr1_"));
18425 #ifdef POWERPC_LINUX
18427 prefix = (savep ? "_savefpr_" : "_restfpr_");
18431 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18432 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18435 else if (DEFAULT_ABI == ABI_DARWIN)
18436 sorry ("Out-of-line save/restore routines not supported on Darwin");
18438 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18440 return savres_routine_name;
18443 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18444 We are saving/restoring GPRs if GPR is true. */
18447 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18450 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18452 int select = ((savep ? 1 : 0) << 2
18454 /* On the SPE, we never have any FPRs, but we do have
18455 32/64-bit versions of the routines. */
18456 ? (info->spe_64bit_regs_used ? 1 : 0)
18457 : (gpr ? 1 : 0)) << 1)
18460 /* Don't generate bogus routine names. */
18461 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18462 && regno <= LAST_SAVRES_REGISTER);
18464 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18470 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18472 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18473 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18474 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18480 /* Emit a sequence of insns, including a stack tie if needed, for
18481 resetting the stack pointer. If SAVRES is true, then don't reset the
18482 stack pointer, but move the base of the frame into r11 for use by
18483 out-of-line register restore routines. */
18486 rs6000_emit_stack_reset (rs6000_stack_t *info,
18487 rtx sp_reg_rtx, rtx frame_reg_rtx,
18488 int sp_offset, bool savres)
18490 /* This blockage is needed so that sched doesn't decide to move
18491 the sp change before the register restores. */
18492 if (frame_reg_rtx != sp_reg_rtx
18494 && info->spe_64bit_regs_used != 0
18495 && info->first_gp_reg_save != 32))
18496 rs6000_emit_stack_tie ();
18498 if (frame_reg_rtx != sp_reg_rtx)
18500 if (sp_offset != 0)
18502 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18503 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18504 GEN_INT (sp_offset)));
18507 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18509 else if (sp_offset != 0)
18511 /* If we are restoring registers out-of-line, we will be using the
18512 "exit" variants of the restore routines, which will reset the
18513 stack for us. But we do need to point r11 into the right place
18514 for those routines. */
18515 rtx dest_reg = (savres
18516 ? gen_rtx_REG (Pmode, 11)
18519 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18520 GEN_INT (sp_offset)));
18527 /* Construct a parallel rtx describing the effect of a call to an
18528 out-of-line register save/restore routine. */
18531 rs6000_make_savres_rtx (rs6000_stack_t *info,
18532 rtx frame_reg_rtx, int save_area_offset,
18533 enum machine_mode reg_mode,
18534 bool savep, bool gpr, bool lr)
18537 int offset, start_reg, end_reg, n_regs;
18538 int reg_size = GET_MODE_SIZE (reg_mode);
18544 ? info->first_gp_reg_save
18545 : info->first_fp_reg_save);
18546 end_reg = gpr ? 32 : 64;
18547 n_regs = end_reg - start_reg;
18548 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18551 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18553 RTVEC_ELT (p, offset++)
18554 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18556 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18557 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18558 RTVEC_ELT (p, offset++)
18559 = gen_rtx_USE (VOIDmode,
18560 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18564 for (i = 0; i < end_reg - start_reg; i++)
18566 rtx addr, reg, mem;
18567 reg = gen_rtx_REG (reg_mode, start_reg + i);
18568 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18569 GEN_INT (save_area_offset + reg_size*i));
18570 mem = gen_frame_mem (reg_mode, addr);
18572 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18574 savep ? reg : mem);
18579 rtx addr, reg, mem;
18580 reg = gen_rtx_REG (Pmode, 0);
18581 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18582 GEN_INT (info->lr_save_offset));
18583 mem = gen_frame_mem (Pmode, addr);
18584 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18587 return gen_rtx_PARALLEL (VOIDmode, p);
18590 /* Determine whether the gp REG is really used. */
18593 rs6000_reg_live_or_pic_offset_p (int reg)
18595 return ((df_regs_ever_live_p (reg)
18596 && (!call_used_regs[reg]
18597 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18598 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18599 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18600 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18601 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18605 SAVRES_MULTIPLE = 0x1,
18606 SAVRES_INLINE_FPRS = 0x2,
18607 SAVRES_INLINE_GPRS = 0x4,
18608 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18609 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18610 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18613 /* Determine the strategy for savings/restoring registers. */
18616 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18617 int using_static_chain_p, int sibcall)
18619 bool using_multiple_p;
18621 bool savres_fprs_inline;
18622 bool savres_gprs_inline;
18623 bool noclobber_global_gprs
18624 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18627 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18628 && (!TARGET_SPE_ABI
18629 || info->spe_64bit_regs_used == 0)
18630 && info->first_gp_reg_save < 31
18631 && noclobber_global_gprs);
18632 /* Don't bother to try to save things out-of-line if r11 is occupied
18633 by the static chain. It would require too much fiddling and the
18634 static chain is rarely used anyway. */
18635 common = (using_static_chain_p
18637 || crtl->calls_eh_return
18638 || !info->lr_save_p
18639 || cfun->machine->ra_need_lr
18640 || info->total_size > 32767);
18641 savres_fprs_inline = (common
18642 || info->first_fp_reg_save == 64
18643 || !no_global_regs_above (info->first_fp_reg_save,
18645 /* The out-of-line FP routines use
18646 double-precision stores; we can't use those
18647 routines if we don't have such stores. */
18648 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18649 || FP_SAVE_INLINE (info->first_fp_reg_save));
18650 savres_gprs_inline = (common
18651 /* Saving CR interferes with the exit routines
18652 used on the SPE, so just punt here. */
18655 && info->spe_64bit_regs_used != 0
18656 && info->cr_save_p != 0)
18657 || info->first_gp_reg_save == 32
18658 || !noclobber_global_gprs
18659 || GP_SAVE_INLINE (info->first_gp_reg_save));
18662 /* If we are going to use store multiple, then don't even bother
18663 with the out-of-line routines, since the store-multiple instruction
18664 will always be smaller. */
18665 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18668 /* The situation is more complicated with load multiple. We'd
18669 prefer to use the out-of-line routines for restores, since the
18670 "exit" out-of-line routines can handle the restore of LR and
18671 the frame teardown. But we can only use the out-of-line
18672 routines if we know that we've used store multiple or
18673 out-of-line routines in the prologue, i.e. if we've saved all
18674 the registers from first_gp_reg_save. Otherwise, we risk
18675 loading garbage from the stack. Furthermore, we can only use
18676 the "exit" out-of-line gpr restore if we haven't saved any
18678 bool saved_all = !savres_gprs_inline || using_multiple_p;
18680 if (saved_all && info->first_fp_reg_save != 64)
18681 /* We can't use the exit routine; use load multiple if it's
18683 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18686 strategy = (using_multiple_p
18687 | (savres_fprs_inline << 1)
18688 | (savres_gprs_inline << 2));
18689 #ifdef POWERPC_LINUX
18692 if (!savres_fprs_inline)
18693 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18694 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18695 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18698 if (TARGET_AIX && !savres_fprs_inline)
18699 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18704 /* Emit function prologue as insns. */
18707 rs6000_emit_prologue (void)
18709 rs6000_stack_t *info = rs6000_stack_info ();
18710 enum machine_mode reg_mode = Pmode;
18711 int reg_size = TARGET_32BIT ? 4 : 8;
18712 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18713 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18714 rtx frame_reg_rtx = sp_reg_rtx;
18715 rtx cr_save_rtx = NULL_RTX;
18718 int saving_FPRs_inline;
18719 int saving_GPRs_inline;
18720 int using_store_multiple;
18721 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18722 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18723 && call_used_regs[STATIC_CHAIN_REGNUM]);
18724 HOST_WIDE_INT sp_offset = 0;
18726 if (TARGET_FIX_AND_CONTINUE)
18728 /* gdb on darwin arranges to forward a function from the old
18729 address by modifying the first 5 instructions of the function
18730 to branch to the overriding function. This is necessary to
18731 permit function pointers that point to the old function to
18732 actually forward to the new function. */
18733 emit_insn (gen_nop ());
18734 emit_insn (gen_nop ());
18735 emit_insn (gen_nop ());
18736 emit_insn (gen_nop ());
18737 emit_insn (gen_nop ());
18740 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18742 reg_mode = V2SImode;
18746 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18747 /*static_chain_p=*/using_static_chain_p,
18749 using_store_multiple = strategy & SAVRES_MULTIPLE;
18750 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18751 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18753 /* For V.4, update stack before we do any saving and set back pointer. */
18754 if (! WORLD_SAVE_P (info)
18756 && (DEFAULT_ABI == ABI_V4
18757 || crtl->calls_eh_return))
18759 bool need_r11 = (TARGET_SPE
18760 ? (!saving_GPRs_inline
18761 && info->spe_64bit_regs_used == 0)
18762 : (!saving_FPRs_inline || !saving_GPRs_inline));
18763 if (info->total_size < 32767)
18764 sp_offset = info->total_size;
18766 frame_reg_rtx = (need_r11
18767 ? gen_rtx_REG (Pmode, 11)
18769 rs6000_emit_allocate_stack (info->total_size,
18770 (frame_reg_rtx != sp_reg_rtx
18771 && (info->cr_save_p
18773 || info->first_fp_reg_save < 64
18774 || info->first_gp_reg_save < 32
18777 if (frame_reg_rtx != sp_reg_rtx)
18778 rs6000_emit_stack_tie ();
18781 /* Handle world saves specially here. */
18782 if (WORLD_SAVE_P (info))
18789 /* save_world expects lr in r0. */
18790 reg0 = gen_rtx_REG (Pmode, 0);
18791 if (info->lr_save_p)
18793 insn = emit_move_insn (reg0,
18794 gen_rtx_REG (Pmode, LR_REGNO));
18795 RTX_FRAME_RELATED_P (insn) = 1;
18798 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18799 assumptions about the offsets of various bits of the stack
18801 gcc_assert (info->gp_save_offset == -220
18802 && info->fp_save_offset == -144
18803 && info->lr_save_offset == 8
18804 && info->cr_save_offset == 4
18807 && (!crtl->calls_eh_return
18808 || info->ehrd_offset == -432)
18809 && info->vrsave_save_offset == -224
18810 && info->altivec_save_offset == -416);
18812 treg = gen_rtx_REG (SImode, 11);
18813 emit_move_insn (treg, GEN_INT (-info->total_size));
18815 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18816 in R11. It also clobbers R12, so beware! */
18818 /* Preserve CR2 for save_world prologues */
18820 sz += 32 - info->first_gp_reg_save;
18821 sz += 64 - info->first_fp_reg_save;
18822 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18823 p = rtvec_alloc (sz);
18825 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18826 gen_rtx_REG (SImode,
18828 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18829 gen_rtx_SYMBOL_REF (Pmode,
18831 /* We do floats first so that the instruction pattern matches
18833 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18835 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18836 ? DFmode : SFmode),
18837 info->first_fp_reg_save + i);
18838 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18839 GEN_INT (info->fp_save_offset
18840 + sp_offset + 8 * i));
18841 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18842 ? DFmode : SFmode), addr);
18844 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18846 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18848 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18849 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18850 GEN_INT (info->altivec_save_offset
18851 + sp_offset + 16 * i));
18852 rtx mem = gen_frame_mem (V4SImode, addr);
18854 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18856 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18858 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18859 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18860 GEN_INT (info->gp_save_offset
18861 + sp_offset + reg_size * i));
18862 rtx mem = gen_frame_mem (reg_mode, addr);
18864 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18868 /* CR register traditionally saved as CR2. */
18869 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18870 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18871 GEN_INT (info->cr_save_offset
18873 rtx mem = gen_frame_mem (reg_mode, addr);
18875 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18877 /* Explain about use of R0. */
18878 if (info->lr_save_p)
18880 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18881 GEN_INT (info->lr_save_offset
18883 rtx mem = gen_frame_mem (reg_mode, addr);
18885 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18887 /* Explain what happens to the stack pointer. */
18889 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18890 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18893 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18894 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18895 treg, GEN_INT (-info->total_size));
18896 sp_offset = info->total_size;
18899 /* If we use the link register, get it into r0. */
18900 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18902 rtx addr, reg, mem;
18904 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18905 gen_rtx_REG (Pmode, LR_REGNO));
18906 RTX_FRAME_RELATED_P (insn) = 1;
18908 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18909 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18911 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18912 GEN_INT (info->lr_save_offset + sp_offset));
18913 reg = gen_rtx_REG (Pmode, 0);
18914 mem = gen_rtx_MEM (Pmode, addr);
18915 /* This should not be of rs6000_sr_alias_set, because of
18916 __builtin_return_address. */
18918 insn = emit_move_insn (mem, reg);
18919 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18920 NULL_RTX, NULL_RTX);
18924 /* If we need to save CR, put it into r12 or r11. */
18925 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18930 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18932 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18933 RTX_FRAME_RELATED_P (insn) = 1;
18934 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18935 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18936 But that's OK. All we have to do is specify that _one_ condition
18937 code register is saved in this stack slot. The thrower's epilogue
18938 will then restore all the call-saved registers.
18939 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18940 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18941 gen_rtx_REG (SImode, CR2_REGNO));
18942 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18945 /* Do any required saving of fpr's. If only one or two to save, do
18946 it ourselves. Otherwise, call function. */
18947 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18950 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18951 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18952 && ! call_used_regs[info->first_fp_reg_save+i]))
18953 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18954 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18956 info->first_fp_reg_save + i,
18957 info->fp_save_offset + sp_offset + 8 * i,
18960 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18964 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18965 info->fp_save_offset + sp_offset,
18967 /*savep=*/true, /*gpr=*/false,
18969 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18971 insn = emit_insn (par);
18972 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18973 NULL_RTX, NULL_RTX);
18976 /* Save GPRs. This is done as a PARALLEL if we are using
18977 the store-multiple instructions. */
18978 if (!WORLD_SAVE_P (info)
18980 && info->spe_64bit_regs_used != 0
18981 && info->first_gp_reg_save != 32)
18984 rtx spe_save_area_ptr;
18986 /* Determine whether we can address all of the registers that need
18987 to be saved with an offset from the stack pointer that fits in
18988 the small const field for SPE memory instructions. */
18989 int spe_regs_addressable_via_sp
18990 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18991 + (32 - info->first_gp_reg_save - 1) * reg_size)
18992 && saving_GPRs_inline);
18995 if (spe_regs_addressable_via_sp)
18997 spe_save_area_ptr = frame_reg_rtx;
18998 spe_offset = info->spe_gp_save_offset + sp_offset;
19002 /* Make r11 point to the start of the SPE save area. We need
19003 to be careful here if r11 is holding the static chain. If
19004 it is, then temporarily save it in r0. We would use r0 as
19005 our base register here, but using r0 as a base register in
19006 loads and stores means something different from what we
19008 int ool_adjust = (saving_GPRs_inline
19010 : (info->first_gp_reg_save
19011 - (FIRST_SAVRES_REGISTER+1))*8);
19012 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19013 + sp_offset - ool_adjust);
19015 if (using_static_chain_p)
19017 rtx r0 = gen_rtx_REG (Pmode, 0);
19018 gcc_assert (info->first_gp_reg_save > 11);
19020 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19023 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19024 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19026 GEN_INT (offset)));
19027 /* We need to make sure the move to r11 gets noted for
19028 properly outputting unwind information. */
19029 if (!saving_GPRs_inline)
19030 rs6000_frame_related (insn, frame_reg_rtx, offset,
19031 NULL_RTX, NULL_RTX);
19035 if (saving_GPRs_inline)
19037 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19038 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19040 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19041 rtx offset, addr, mem;
19043 /* We're doing all this to ensure that the offset fits into
19044 the immediate offset of 'evstdd'. */
19045 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19047 offset = GEN_INT (reg_size * i + spe_offset);
19048 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19049 mem = gen_rtx_MEM (V2SImode, addr);
19051 insn = emit_move_insn (mem, reg);
19053 rs6000_frame_related (insn, spe_save_area_ptr,
19054 info->spe_gp_save_offset
19055 + sp_offset + reg_size * i,
19056 offset, const0_rtx);
19063 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19065 /*savep=*/true, /*gpr=*/true,
19067 insn = emit_insn (par);
19068 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19069 NULL_RTX, NULL_RTX);
19073 /* Move the static chain pointer back. */
19074 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19075 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19077 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19081 /* Need to adjust r11 (r12) if we saved any FPRs. */
19082 if (info->first_fp_reg_save != 64)
19084 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19086 rtx offset = GEN_INT (sp_offset
19087 + (-8 * (64-info->first_fp_reg_save)));
19088 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19091 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19092 info->gp_save_offset + sp_offset,
19094 /*savep=*/true, /*gpr=*/true,
19096 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19098 insn = emit_insn (par);
19099 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19100 NULL_RTX, NULL_RTX);
19102 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19106 p = rtvec_alloc (32 - info->first_gp_reg_save);
19107 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19109 rtx addr, reg, mem;
19110 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19111 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19112 GEN_INT (info->gp_save_offset
19115 mem = gen_frame_mem (reg_mode, addr);
19117 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19119 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19120 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19121 NULL_RTX, NULL_RTX);
19123 else if (!WORLD_SAVE_P (info))
19126 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19127 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19129 rtx addr, reg, mem;
19130 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19132 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19133 GEN_INT (info->gp_save_offset
19136 mem = gen_frame_mem (reg_mode, addr);
19138 insn = emit_move_insn (mem, reg);
19139 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19140 NULL_RTX, NULL_RTX);
19144 /* ??? There's no need to emit actual instructions here, but it's the
19145 easiest way to get the frame unwind information emitted. */
19146 if (crtl->calls_eh_return)
19148 unsigned int i, regno;
19150 /* In AIX ABI we need to pretend we save r2 here. */
19153 rtx addr, reg, mem;
19155 reg = gen_rtx_REG (reg_mode, 2);
19156 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19157 GEN_INT (sp_offset + 5 * reg_size));
19158 mem = gen_frame_mem (reg_mode, addr);
19160 insn = emit_move_insn (mem, reg);
19161 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19162 NULL_RTX, NULL_RTX);
19163 PATTERN (insn) = gen_blockage ();
19168 regno = EH_RETURN_DATA_REGNO (i);
19169 if (regno == INVALID_REGNUM)
19172 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19173 info->ehrd_offset + sp_offset
19174 + reg_size * (int) i,
19179 /* Save CR if we use any that must be preserved. */
19180 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19182 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19183 GEN_INT (info->cr_save_offset + sp_offset));
19184 rtx mem = gen_frame_mem (SImode, addr);
19185 /* See the large comment above about why CR2_REGNO is used. */
19186 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19188 /* If r12 was used to hold the original sp, copy cr into r0 now
19190 if (REGNO (frame_reg_rtx) == 12)
19194 cr_save_rtx = gen_rtx_REG (SImode, 0);
19195 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19196 RTX_FRAME_RELATED_P (insn) = 1;
19197 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19198 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19200 insn = emit_move_insn (mem, cr_save_rtx);
19202 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19203 NULL_RTX, NULL_RTX);
19206 /* Update stack and set back pointer unless this is V.4,
19207 for which it was done previously. */
19208 if (!WORLD_SAVE_P (info) && info->push_p
19209 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19211 if (info->total_size < 32767)
19212 sp_offset = info->total_size;
19214 frame_reg_rtx = frame_ptr_rtx;
19215 rs6000_emit_allocate_stack (info->total_size,
19216 (frame_reg_rtx != sp_reg_rtx
19217 && ((info->altivec_size != 0)
19218 || (info->vrsave_mask != 0)
19221 if (frame_reg_rtx != sp_reg_rtx)
19222 rs6000_emit_stack_tie ();
19225 /* Set frame pointer, if needed. */
19226 if (frame_pointer_needed)
19228 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19230 RTX_FRAME_RELATED_P (insn) = 1;
19233 /* Save AltiVec registers if needed. Save here because the red zone does
19234 not include AltiVec registers. */
19235 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19239 /* There should be a non inline version of this, for when we
19240 are saving lots of vector registers. */
19241 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19242 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19244 rtx areg, savereg, mem;
19247 offset = info->altivec_save_offset + sp_offset
19248 + 16 * (i - info->first_altivec_reg_save);
19250 savereg = gen_rtx_REG (V4SImode, i);
19252 areg = gen_rtx_REG (Pmode, 0);
19253 emit_move_insn (areg, GEN_INT (offset));
19255 /* AltiVec addressing mode is [reg+reg]. */
19256 mem = gen_frame_mem (V4SImode,
19257 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19259 insn = emit_move_insn (mem, savereg);
19261 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19262 areg, GEN_INT (offset));
19266 /* VRSAVE is a bit vector representing which AltiVec registers
19267 are used. The OS uses this to determine which vector
19268 registers to save on a context switch. We need to save
19269 VRSAVE on the stack frame, add whatever AltiVec registers we
19270 used in this function, and do the corresponding magic in the
19273 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19274 && info->vrsave_mask != 0)
19276 rtx reg, mem, vrsave;
19279 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19280 as frame_reg_rtx and r11 as the static chain pointer for
19281 nested functions. */
19282 reg = gen_rtx_REG (SImode, 0);
19283 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19285 emit_insn (gen_get_vrsave_internal (reg));
19287 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19289 if (!WORLD_SAVE_P (info))
19292 offset = info->vrsave_save_offset + sp_offset;
19293 mem = gen_frame_mem (SImode,
19294 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19295 GEN_INT (offset)));
19296 insn = emit_move_insn (mem, reg);
19299 /* Include the registers in the mask. */
19300 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19302 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19305 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19306 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19307 || (DEFAULT_ABI == ABI_V4
19308 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19309 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19311 /* If emit_load_toc_table will use the link register, we need to save
19312 it. We use R12 for this purpose because emit_load_toc_table
19313 can use register 0. This allows us to use a plain 'blr' to return
19314 from the procedure more often. */
19315 int save_LR_around_toc_setup = (TARGET_ELF
19316 && DEFAULT_ABI != ABI_AIX
19318 && ! info->lr_save_p
19319 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19320 if (save_LR_around_toc_setup)
19322 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19324 insn = emit_move_insn (frame_ptr_rtx, lr);
19325 RTX_FRAME_RELATED_P (insn) = 1;
19327 rs6000_emit_load_toc_table (TRUE);
19329 insn = emit_move_insn (lr, frame_ptr_rtx);
19330 RTX_FRAME_RELATED_P (insn) = 1;
19333 rs6000_emit_load_toc_table (TRUE);
19337 if (DEFAULT_ABI == ABI_DARWIN
19338 && flag_pic && crtl->uses_pic_offset_table)
19340 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19341 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19343 /* Save and restore LR locally around this call (in R0). */
19344 if (!info->lr_save_p)
19345 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19347 emit_insn (gen_load_macho_picbase (src));
19349 emit_move_insn (gen_rtx_REG (Pmode,
19350 RS6000_PIC_OFFSET_TABLE_REGNUM),
19353 if (!info->lr_save_p)
19354 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19359 /* Write function prologue. */
19362 rs6000_output_function_prologue (FILE *file,
19363 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19365 rs6000_stack_t *info = rs6000_stack_info ();
19367 if (TARGET_DEBUG_STACK)
19368 debug_stack_info (info);
19370 /* Write .extern for any function we will call to save and restore
19372 if (info->first_fp_reg_save < 64
19373 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19376 int regno = info->first_fp_reg_save - 32;
19378 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19379 /*gpr=*/false, /*lr=*/false);
19380 fprintf (file, "\t.extern %s\n", name);
19382 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19383 /*gpr=*/false, /*lr=*/true);
19384 fprintf (file, "\t.extern %s\n", name);
19387 /* Write .extern for AIX common mode routines, if needed. */
19388 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19390 fputs ("\t.extern __mulh\n", file);
19391 fputs ("\t.extern __mull\n", file);
19392 fputs ("\t.extern __divss\n", file);
19393 fputs ("\t.extern __divus\n", file);
19394 fputs ("\t.extern __quoss\n", file);
19395 fputs ("\t.extern __quous\n", file);
19396 common_mode_defined = 1;
19399 if (! HAVE_prologue)
19405 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19406 the "toplevel" insn chain. */
19407 emit_note (NOTE_INSN_DELETED);
19408 rs6000_emit_prologue ();
19409 emit_note (NOTE_INSN_DELETED);
19411 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19415 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19417 INSN_ADDRESSES_NEW (insn, addr);
19422 prologue = get_insns ();
19425 if (TARGET_DEBUG_STACK)
19426 debug_rtx_list (prologue, 100);
19428 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19432 rs6000_pic_labelno++;
19435 /* Non-zero if vmx regs are restored before the frame pop, zero if
19436 we restore after the pop when possible. */
19437 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19439 /* Reload CR from REG. */
19442 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19447 if (using_mfcr_multiple)
19449 for (i = 0; i < 8; i++)
19450 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19452 gcc_assert (count);
19455 if (using_mfcr_multiple && count > 1)
19460 p = rtvec_alloc (count);
19463 for (i = 0; i < 8; i++)
19464 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19466 rtvec r = rtvec_alloc (2);
19467 RTVEC_ELT (r, 0) = reg;
19468 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19469 RTVEC_ELT (p, ndx) =
19470 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19471 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19474 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19475 gcc_assert (ndx == count);
19478 for (i = 0; i < 8; i++)
19479 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19481 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19487 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19488 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19489 below stack pointer not cloberred by signals. */
19492 offset_below_red_zone_p (HOST_WIDE_INT offset)
19494 return offset < (DEFAULT_ABI == ABI_V4
19496 : TARGET_32BIT ? -220 : -288);
19499 /* Emit function epilogue as insns. */
19502 rs6000_emit_epilogue (int sibcall)
19504 rs6000_stack_t *info;
19505 int restoring_GPRs_inline;
19506 int restoring_FPRs_inline;
19507 int using_load_multiple;
19508 int using_mtcr_multiple;
19509 int use_backchain_to_restore_sp;
19513 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19514 rtx frame_reg_rtx = sp_reg_rtx;
19515 rtx cfa_restores = NULL_RTX;
19517 rtx cr_save_reg = NULL_RTX;
19518 enum machine_mode reg_mode = Pmode;
19519 int reg_size = TARGET_32BIT ? 4 : 8;
19522 info = rs6000_stack_info ();
19524 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19526 reg_mode = V2SImode;
19530 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19531 /*static_chain_p=*/0, sibcall);
19532 using_load_multiple = strategy & SAVRES_MULTIPLE;
19533 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19534 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19535 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19536 || rs6000_cpu == PROCESSOR_PPC603
19537 || rs6000_cpu == PROCESSOR_PPC750
19539 /* Restore via the backchain when we have a large frame, since this
19540 is more efficient than an addis, addi pair. The second condition
19541 here will not trigger at the moment; We don't actually need a
19542 frame pointer for alloca, but the generic parts of the compiler
19543 give us one anyway. */
19544 use_backchain_to_restore_sp = (info->total_size > 32767
19545 || info->total_size
19546 + (info->lr_save_p ? info->lr_save_offset : 0)
19548 || (cfun->calls_alloca
19549 && !frame_pointer_needed));
19550 restore_lr = (info->lr_save_p
19551 && (restoring_FPRs_inline
19552 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19553 && (restoring_GPRs_inline
19554 || info->first_fp_reg_save < 64));
19556 if (WORLD_SAVE_P (info))
19560 const char *alloc_rname;
19563 /* eh_rest_world_r10 will return to the location saved in the LR
19564 stack slot (which is not likely to be our caller.)
19565 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19566 rest_world is similar, except any R10 parameter is ignored.
19567 The exception-handling stuff that was here in 2.95 is no
19568 longer necessary. */
19572 + 32 - info->first_gp_reg_save
19573 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19574 + 63 + 1 - info->first_fp_reg_save);
19576 strcpy (rname, ((crtl->calls_eh_return) ?
19577 "*eh_rest_world_r10" : "*rest_world"));
19578 alloc_rname = ggc_strdup (rname);
19581 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19582 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19583 gen_rtx_REG (Pmode,
19586 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19587 /* The instruction pattern requires a clobber here;
19588 it is shared with the restVEC helper. */
19590 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19593 /* CR register traditionally saved as CR2. */
19594 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19595 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19596 GEN_INT (info->cr_save_offset));
19597 rtx mem = gen_frame_mem (reg_mode, addr);
19599 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19602 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19604 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19605 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19606 GEN_INT (info->gp_save_offset
19608 rtx mem = gen_frame_mem (reg_mode, addr);
19610 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19612 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19614 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19615 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19616 GEN_INT (info->altivec_save_offset
19618 rtx mem = gen_frame_mem (V4SImode, addr);
19620 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19622 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19624 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19625 ? DFmode : SFmode),
19626 info->first_fp_reg_save + i);
19627 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19628 GEN_INT (info->fp_save_offset
19630 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19631 ? DFmode : SFmode), addr);
19633 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19636 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19638 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19640 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19642 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19644 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19645 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19650 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19652 sp_offset = info->total_size;
19654 /* Restore AltiVec registers if we must do so before adjusting the
19656 if (TARGET_ALTIVEC_ABI
19657 && info->altivec_size != 0
19658 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19659 || (DEFAULT_ABI != ABI_V4
19660 && offset_below_red_zone_p (info->altivec_save_offset))))
19664 if (use_backchain_to_restore_sp)
19666 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19667 emit_move_insn (frame_reg_rtx,
19668 gen_rtx_MEM (Pmode, sp_reg_rtx));
19671 else if (frame_pointer_needed)
19672 frame_reg_rtx = hard_frame_pointer_rtx;
19674 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19675 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19677 rtx addr, areg, mem, reg;
19679 areg = gen_rtx_REG (Pmode, 0);
19681 (areg, GEN_INT (info->altivec_save_offset
19683 + 16 * (i - info->first_altivec_reg_save)));
19685 /* AltiVec addressing mode is [reg+reg]. */
19686 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19687 mem = gen_frame_mem (V4SImode, addr);
19689 reg = gen_rtx_REG (V4SImode, i);
19690 emit_move_insn (reg, mem);
19691 if (offset_below_red_zone_p (info->altivec_save_offset
19692 + (i - info->first_altivec_reg_save)
19694 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19699 /* Restore VRSAVE if we must do so before adjusting the stack. */
19701 && TARGET_ALTIVEC_VRSAVE
19702 && info->vrsave_mask != 0
19703 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19704 || (DEFAULT_ABI != ABI_V4
19705 && offset_below_red_zone_p (info->vrsave_save_offset))))
19707 rtx addr, mem, reg;
19709 if (frame_reg_rtx == sp_reg_rtx)
19711 if (use_backchain_to_restore_sp)
19713 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19714 emit_move_insn (frame_reg_rtx,
19715 gen_rtx_MEM (Pmode, sp_reg_rtx));
19718 else if (frame_pointer_needed)
19719 frame_reg_rtx = hard_frame_pointer_rtx;
19722 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19723 GEN_INT (info->vrsave_save_offset + sp_offset));
19724 mem = gen_frame_mem (SImode, addr);
19725 reg = gen_rtx_REG (SImode, 12);
19726 emit_move_insn (reg, mem);
19728 emit_insn (generate_set_vrsave (reg, info, 1));
19732 /* If we have a large stack frame, restore the old stack pointer
19733 using the backchain. */
19734 if (use_backchain_to_restore_sp)
19736 if (frame_reg_rtx == sp_reg_rtx)
19738 /* Under V.4, don't reset the stack pointer until after we're done
19739 loading the saved registers. */
19740 if (DEFAULT_ABI == ABI_V4)
19741 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19743 insn = emit_move_insn (frame_reg_rtx,
19744 gen_rtx_MEM (Pmode, sp_reg_rtx));
19747 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19748 && DEFAULT_ABI == ABI_V4)
19749 /* frame_reg_rtx has been set up by the altivec restore. */
19753 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19754 frame_reg_rtx = sp_reg_rtx;
19757 /* If we have a frame pointer, we can restore the old stack pointer
19759 else if (frame_pointer_needed)
19761 frame_reg_rtx = sp_reg_rtx;
19762 if (DEFAULT_ABI == ABI_V4)
19763 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19765 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19766 GEN_INT (info->total_size)));
19769 else if (info->push_p
19770 && DEFAULT_ABI != ABI_V4
19771 && !crtl->calls_eh_return)
19773 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19774 GEN_INT (info->total_size)));
19777 if (insn && frame_reg_rtx == sp_reg_rtx)
19781 REG_NOTES (insn) = cfa_restores;
19782 cfa_restores = NULL_RTX;
19784 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19785 RTX_FRAME_RELATED_P (insn) = 1;
19788 /* Restore AltiVec registers if we have not done so already. */
19789 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19790 && TARGET_ALTIVEC_ABI
19791 && info->altivec_size != 0
19792 && (DEFAULT_ABI == ABI_V4
19793 || !offset_below_red_zone_p (info->altivec_save_offset)))
19797 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19798 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19800 rtx addr, areg, mem, reg;
19802 areg = gen_rtx_REG (Pmode, 0);
19804 (areg, GEN_INT (info->altivec_save_offset
19806 + 16 * (i - info->first_altivec_reg_save)));
19808 /* AltiVec addressing mode is [reg+reg]. */
19809 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19810 mem = gen_frame_mem (V4SImode, addr);
19812 reg = gen_rtx_REG (V4SImode, i);
19813 emit_move_insn (reg, mem);
19814 if (DEFAULT_ABI == ABI_V4)
19815 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19820 /* Restore VRSAVE if we have not done so already. */
19821 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19823 && TARGET_ALTIVEC_VRSAVE
19824 && info->vrsave_mask != 0
19825 && (DEFAULT_ABI == ABI_V4
19826 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19828 rtx addr, mem, reg;
19830 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19831 GEN_INT (info->vrsave_save_offset + sp_offset));
19832 mem = gen_frame_mem (SImode, addr);
19833 reg = gen_rtx_REG (SImode, 12);
19834 emit_move_insn (reg, mem);
19836 emit_insn (generate_set_vrsave (reg, info, 1));
19839 /* Get the old lr if we saved it. If we are restoring registers
19840 out-of-line, then the out-of-line routines can do this for us. */
19841 if (restore_lr && restoring_GPRs_inline)
19843 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19844 info->lr_save_offset + sp_offset);
19846 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19849 /* Get the old cr if we saved it. */
19850 if (info->cr_save_p)
19852 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19853 GEN_INT (info->cr_save_offset + sp_offset));
19854 rtx mem = gen_frame_mem (SImode, addr);
19856 cr_save_reg = gen_rtx_REG (SImode,
19857 DEFAULT_ABI == ABI_AIX
19858 && !restoring_GPRs_inline
19859 && info->first_fp_reg_save < 64
19861 emit_move_insn (cr_save_reg, mem);
19864 /* Set LR here to try to overlap restores below. LR is always saved
19865 above incoming stack, so it never needs REG_CFA_RESTORE. */
19866 if (restore_lr && restoring_GPRs_inline)
19867 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19868 gen_rtx_REG (Pmode, 0));
19870 /* Load exception handler data registers, if needed. */
19871 if (crtl->calls_eh_return)
19873 unsigned int i, regno;
19877 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19878 GEN_INT (sp_offset + 5 * reg_size));
19879 rtx mem = gen_frame_mem (reg_mode, addr);
19881 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19888 regno = EH_RETURN_DATA_REGNO (i);
19889 if (regno == INVALID_REGNUM)
19892 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19893 info->ehrd_offset + sp_offset
19894 + reg_size * (int) i);
19896 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19900 /* Restore GPRs. This is done as a PARALLEL if we are using
19901 the load-multiple instructions. */
19903 && info->spe_64bit_regs_used != 0
19904 && info->first_gp_reg_save != 32)
19906 /* Determine whether we can address all of the registers that need
19907 to be saved with an offset from the stack pointer that fits in
19908 the small const field for SPE memory instructions. */
19909 int spe_regs_addressable_via_sp
19910 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19911 + (32 - info->first_gp_reg_save - 1) * reg_size)
19912 && restoring_GPRs_inline);
19915 if (spe_regs_addressable_via_sp)
19916 spe_offset = info->spe_gp_save_offset + sp_offset;
19919 rtx old_frame_reg_rtx = frame_reg_rtx;
19920 /* Make r11 point to the start of the SPE save area. We worried about
19921 not clobbering it when we were saving registers in the prologue.
19922 There's no need to worry here because the static chain is passed
19923 anew to every function. */
19924 int ool_adjust = (restoring_GPRs_inline
19926 : (info->first_gp_reg_save
19927 - (FIRST_SAVRES_REGISTER+1))*8);
19929 if (frame_reg_rtx == sp_reg_rtx)
19930 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19931 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19932 GEN_INT (info->spe_gp_save_offset
19935 /* Keep the invariant that frame_reg_rtx + sp_offset points
19936 at the top of the stack frame. */
19937 sp_offset = -info->spe_gp_save_offset;
19942 if (restoring_GPRs_inline)
19944 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19945 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19947 rtx offset, addr, mem, reg;
19949 /* We're doing all this to ensure that the immediate offset
19950 fits into the immediate field of 'evldd'. */
19951 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19953 offset = GEN_INT (spe_offset + reg_size * i);
19954 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19955 mem = gen_rtx_MEM (V2SImode, addr);
19956 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19958 insn = emit_move_insn (reg, mem);
19959 if (DEFAULT_ABI == ABI_V4)
19961 if (frame_pointer_needed
19962 && info->first_gp_reg_save + i
19963 == HARD_FRAME_POINTER_REGNUM)
19965 add_reg_note (insn, REG_CFA_DEF_CFA,
19966 plus_constant (frame_reg_rtx,
19968 RTX_FRAME_RELATED_P (insn) = 1;
19971 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19980 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19982 /*savep=*/false, /*gpr=*/true,
19984 emit_jump_insn (par);
19985 /* We don't want anybody else emitting things after we jumped
19990 else if (!restoring_GPRs_inline)
19992 /* We are jumping to an out-of-line function. */
19993 bool can_use_exit = info->first_fp_reg_save == 64;
19996 /* Emit stack reset code if we need it. */
19998 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19999 sp_offset, can_use_exit);
20002 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20005 GEN_INT (sp_offset - info->fp_size)));
20006 if (REGNO (frame_reg_rtx) == 11)
20007 sp_offset += info->fp_size;
20010 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20011 info->gp_save_offset, reg_mode,
20012 /*savep=*/false, /*gpr=*/true,
20013 /*lr=*/can_use_exit);
20017 if (info->cr_save_p)
20019 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20020 if (DEFAULT_ABI == ABI_V4)
20022 = alloc_reg_note (REG_CFA_RESTORE,
20023 gen_rtx_REG (SImode, CR2_REGNO),
20027 emit_jump_insn (par);
20029 /* We don't want anybody else emitting things after we jumped
20034 insn = emit_insn (par);
20035 if (DEFAULT_ABI == ABI_V4)
20037 if (frame_pointer_needed)
20039 add_reg_note (insn, REG_CFA_DEF_CFA,
20040 plus_constant (frame_reg_rtx, sp_offset));
20041 RTX_FRAME_RELATED_P (insn) = 1;
20044 for (i = info->first_gp_reg_save; i < 32; i++)
20046 = alloc_reg_note (REG_CFA_RESTORE,
20047 gen_rtx_REG (reg_mode, i), cfa_restores);
20050 else if (using_load_multiple)
20053 p = rtvec_alloc (32 - info->first_gp_reg_save);
20054 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20056 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20057 GEN_INT (info->gp_save_offset
20060 rtx mem = gen_frame_mem (reg_mode, addr);
20061 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20063 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20064 if (DEFAULT_ABI == ABI_V4)
20065 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20068 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20069 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20071 add_reg_note (insn, REG_CFA_DEF_CFA,
20072 plus_constant (frame_reg_rtx, sp_offset));
20073 RTX_FRAME_RELATED_P (insn) = 1;
20078 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20079 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20081 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20082 GEN_INT (info->gp_save_offset
20085 rtx mem = gen_frame_mem (reg_mode, addr);
20086 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20088 insn = emit_move_insn (reg, mem);
20089 if (DEFAULT_ABI == ABI_V4)
20091 if (frame_pointer_needed
20092 && info->first_gp_reg_save + i
20093 == HARD_FRAME_POINTER_REGNUM)
20095 add_reg_note (insn, REG_CFA_DEF_CFA,
20096 plus_constant (frame_reg_rtx, sp_offset));
20097 RTX_FRAME_RELATED_P (insn) = 1;
20100 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20106 if (restore_lr && !restoring_GPRs_inline)
20108 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20109 info->lr_save_offset + sp_offset);
20111 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20112 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20113 gen_rtx_REG (Pmode, 0));
20116 /* Restore fpr's if we need to do it without calling a function. */
20117 if (restoring_FPRs_inline)
20118 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20119 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20120 && ! call_used_regs[info->first_fp_reg_save+i]))
20122 rtx addr, mem, reg;
20123 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20124 GEN_INT (info->fp_save_offset
20127 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20128 ? DFmode : SFmode), addr);
20129 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20130 ? DFmode : SFmode),
20131 info->first_fp_reg_save + i);
20133 emit_move_insn (reg, mem);
20134 if (DEFAULT_ABI == ABI_V4)
20135 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20139 /* If we saved cr, restore it here. Just those that were used. */
20140 if (info->cr_save_p)
20142 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20143 if (DEFAULT_ABI == ABI_V4)
20145 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20149 /* If this is V.4, unwind the stack pointer after all of the loads
20151 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20152 sp_offset, !restoring_FPRs_inline);
20157 REG_NOTES (insn) = cfa_restores;
20158 cfa_restores = NULL_RTX;
20160 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20161 RTX_FRAME_RELATED_P (insn) = 1;
20164 if (crtl->calls_eh_return)
20166 rtx sa = EH_RETURN_STACKADJ_RTX;
20167 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20173 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20174 if (! restoring_FPRs_inline)
20175 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20177 p = rtvec_alloc (2);
20179 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20180 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20181 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20182 : gen_rtx_CLOBBER (VOIDmode,
20183 gen_rtx_REG (Pmode, 65)));
20185 /* If we have to restore more than two FP registers, branch to the
20186 restore function. It will return to our caller. */
20187 if (! restoring_FPRs_inline)
20192 sym = rs6000_savres_routine_sym (info,
20196 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20197 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20198 gen_rtx_REG (Pmode,
20199 DEFAULT_ABI == ABI_AIX
20201 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20204 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20205 GEN_INT (info->fp_save_offset + 8*i));
20206 mem = gen_frame_mem (DFmode, addr);
20208 RTVEC_ELT (p, i+4) =
20209 gen_rtx_SET (VOIDmode,
20210 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20215 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20219 /* Write function epilogue. */
20222 rs6000_output_function_epilogue (FILE *file,
20223 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20225 if (! HAVE_epilogue)
20227 rtx insn = get_last_insn ();
20228 /* If the last insn was a BARRIER, we don't have to write anything except
20229 the trace table. */
20230 if (GET_CODE (insn) == NOTE)
20231 insn = prev_nonnote_insn (insn);
20232 if (insn == 0 || GET_CODE (insn) != BARRIER)
20234 /* This is slightly ugly, but at least we don't have two
20235 copies of the epilogue-emitting code. */
20238 /* A NOTE_INSN_DELETED is supposed to be at the start
20239 and end of the "toplevel" insn chain. */
20240 emit_note (NOTE_INSN_DELETED);
20241 rs6000_emit_epilogue (FALSE);
20242 emit_note (NOTE_INSN_DELETED);
20244 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20248 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20250 INSN_ADDRESSES_NEW (insn, addr);
20255 if (TARGET_DEBUG_STACK)
20256 debug_rtx_list (get_insns (), 100);
20257 final (get_insns (), file, FALSE);
20263 macho_branch_islands ();
20264 /* Mach-O doesn't support labels at the end of objects, so if
20265 it looks like we might want one, insert a NOP. */
20267 rtx insn = get_last_insn ();
20270 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20271 insn = PREV_INSN (insn);
20275 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20276 fputs ("\tnop\n", file);
20280 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20283 We don't output a traceback table if -finhibit-size-directive was
20284 used. The documentation for -finhibit-size-directive reads
20285 ``don't output a @code{.size} assembler directive, or anything
20286 else that would cause trouble if the function is split in the
20287 middle, and the two halves are placed at locations far apart in
20288 memory.'' The traceback table has this property, since it
20289 includes the offset from the start of the function to the
20290 traceback table itself.
20292 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20293 different traceback table. */
20294 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20295 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20297 const char *fname = NULL;
20298 const char *language_string = lang_hooks.name;
20299 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20301 int optional_tbtab;
20302 rs6000_stack_t *info = rs6000_stack_info ();
20304 if (rs6000_traceback == traceback_full)
20305 optional_tbtab = 1;
20306 else if (rs6000_traceback == traceback_part)
20307 optional_tbtab = 0;
20309 optional_tbtab = !optimize_size && !TARGET_ELF;
20311 if (optional_tbtab)
20313 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20314 while (*fname == '.') /* V.4 encodes . in the name */
20317 /* Need label immediately before tbtab, so we can compute
20318 its offset from the function start. */
20319 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20320 ASM_OUTPUT_LABEL (file, fname);
20323 /* The .tbtab pseudo-op can only be used for the first eight
20324 expressions, since it can't handle the possibly variable
20325 length fields that follow. However, if you omit the optional
20326 fields, the assembler outputs zeros for all optional fields
20327 anyways, giving each variable length field is minimum length
20328 (as defined in sys/debug.h). Thus we can not use the .tbtab
20329 pseudo-op at all. */
20331 /* An all-zero word flags the start of the tbtab, for debuggers
20332 that have to find it by searching forward from the entry
20333 point or from the current pc. */
20334 fputs ("\t.long 0\n", file);
20336 /* Tbtab format type. Use format type 0. */
20337 fputs ("\t.byte 0,", file);
20339 /* Language type. Unfortunately, there does not seem to be any
20340 official way to discover the language being compiled, so we
20341 use language_string.
20342 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20343 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20344 a number, so for now use 9. LTO isn't assigned a number either,
20345 so for now use 0. */
20346 if (! strcmp (language_string, "GNU C")
20347 || ! strcmp (language_string, "GNU GIMPLE"))
20349 else if (! strcmp (language_string, "GNU F77")
20350 || ! strcmp (language_string, "GNU Fortran"))
20352 else if (! strcmp (language_string, "GNU Pascal"))
20354 else if (! strcmp (language_string, "GNU Ada"))
20356 else if (! strcmp (language_string, "GNU C++")
20357 || ! strcmp (language_string, "GNU Objective-C++"))
20359 else if (! strcmp (language_string, "GNU Java"))
20361 else if (! strcmp (language_string, "GNU Objective-C"))
20364 gcc_unreachable ();
20365 fprintf (file, "%d,", i);
20367 /* 8 single bit fields: global linkage (not set for C extern linkage,
20368 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20369 from start of procedure stored in tbtab, internal function, function
20370 has controlled storage, function has no toc, function uses fp,
20371 function logs/aborts fp operations. */
20372 /* Assume that fp operations are used if any fp reg must be saved. */
20373 fprintf (file, "%d,",
20374 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20376 /* 6 bitfields: function is interrupt handler, name present in
20377 proc table, function calls alloca, on condition directives
20378 (controls stack walks, 3 bits), saves condition reg, saves
20380 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20381 set up as a frame pointer, even when there is no alloca call. */
20382 fprintf (file, "%d,",
20383 ((optional_tbtab << 6)
20384 | ((optional_tbtab & frame_pointer_needed) << 5)
20385 | (info->cr_save_p << 1)
20386 | (info->lr_save_p)));
20388 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20390 fprintf (file, "%d,",
20391 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20393 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20394 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20396 if (optional_tbtab)
20398 /* Compute the parameter info from the function decl argument
20401 int next_parm_info_bit = 31;
20403 for (decl = DECL_ARGUMENTS (current_function_decl);
20404 decl; decl = TREE_CHAIN (decl))
20406 rtx parameter = DECL_INCOMING_RTL (decl);
20407 enum machine_mode mode = GET_MODE (parameter);
20409 if (GET_CODE (parameter) == REG)
20411 if (SCALAR_FLOAT_MODE_P (mode))
20432 gcc_unreachable ();
20435 /* If only one bit will fit, don't or in this entry. */
20436 if (next_parm_info_bit > 0)
20437 parm_info |= (bits << (next_parm_info_bit - 1));
20438 next_parm_info_bit -= 2;
20442 fixed_parms += ((GET_MODE_SIZE (mode)
20443 + (UNITS_PER_WORD - 1))
20445 next_parm_info_bit -= 1;
20451 /* Number of fixed point parameters. */
20452 /* This is actually the number of words of fixed point parameters; thus
20453 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20454 fprintf (file, "%d,", fixed_parms);
20456 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20458 /* This is actually the number of fp registers that hold parameters;
20459 and thus the maximum value is 13. */
20460 /* Set parameters on stack bit if parameters are not in their original
20461 registers, regardless of whether they are on the stack? Xlc
20462 seems to set the bit when not optimizing. */
20463 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20465 if (! optional_tbtab)
20468 /* Optional fields follow. Some are variable length. */
20470 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20471 11 double float. */
20472 /* There is an entry for each parameter in a register, in the order that
20473 they occur in the parameter list. Any intervening arguments on the
20474 stack are ignored. If the list overflows a long (max possible length
20475 34 bits) then completely leave off all elements that don't fit. */
20476 /* Only emit this long if there was at least one parameter. */
20477 if (fixed_parms || float_parms)
20478 fprintf (file, "\t.long %d\n", parm_info);
20480 /* Offset from start of code to tb table. */
20481 fputs ("\t.long ", file);
20482 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20484 RS6000_OUTPUT_BASENAME (file, fname);
20486 assemble_name (file, fname);
20488 rs6000_output_function_entry (file, fname);
20491 /* Interrupt handler mask. */
20492 /* Omit this long, since we never set the interrupt handler bit
20495 /* Number of CTL (controlled storage) anchors. */
20496 /* Omit this long, since the has_ctl bit is never set above. */
20498 /* Displacement into stack of each CTL anchor. */
20499 /* Omit this list of longs, because there are no CTL anchors. */
20501 /* Length of function name. */
20504 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20506 /* Function name. */
20507 assemble_string (fname, strlen (fname));
20509 /* Register for alloca automatic storage; this is always reg 31.
20510 Only emit this if the alloca bit was set above. */
20511 if (frame_pointer_needed)
20512 fputs ("\t.byte 31\n", file);
20514 fputs ("\t.align 2\n", file);
20518 /* A C compound statement that outputs the assembler code for a thunk
20519 function, used to implement C++ virtual function calls with
20520 multiple inheritance. The thunk acts as a wrapper around a virtual
20521 function, adjusting the implicit object parameter before handing
20522 control off to the real function.
20524 First, emit code to add the integer DELTA to the location that
20525 contains the incoming first argument. Assume that this argument
20526 contains a pointer, and is the one used to pass the `this' pointer
20527 in C++. This is the incoming argument *before* the function
20528 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20529 values of all other incoming arguments.
20531 After the addition, emit code to jump to FUNCTION, which is a
20532 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20533 not touch the return address. Hence returning from FUNCTION will
20534 return to whoever called the current `thunk'.
20536 The effect must be as if FUNCTION had been called directly with the
20537 adjusted first argument. This macro is responsible for emitting
20538 all of the code for a thunk function; output_function_prologue()
20539 and output_function_epilogue() are not invoked.
20541 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20542 been extracted from it.) It might possibly be useful on some
20543 targets, but probably not.
20545 If you do not define this macro, the target-independent code in the
20546 C++ frontend will generate a less efficient heavyweight thunk that
20547 calls FUNCTION instead of jumping to it. The generic approach does
20548 not support varargs. */
20551 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20552 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20555 rtx this_rtx, insn, funexp;
20557 reload_completed = 1;
20558 epilogue_completed = 1;
20560 /* Mark the end of the (empty) prologue. */
20561 emit_note (NOTE_INSN_PROLOGUE_END);
20563 /* Find the "this" pointer. If the function returns a structure,
20564 the structure return pointer is in r3. */
20565 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20566 this_rtx = gen_rtx_REG (Pmode, 4);
20568 this_rtx = gen_rtx_REG (Pmode, 3);
20570 /* Apply the constant offset, if required. */
20572 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20574 /* Apply the offset from the vtable, if required. */
20577 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20578 rtx tmp = gen_rtx_REG (Pmode, 12);
20580 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20581 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20583 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20584 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20588 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20590 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20592 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20595 /* Generate a tail call to the target function. */
20596 if (!TREE_USED (function))
20598 assemble_external (function);
20599 TREE_USED (function) = 1;
20601 funexp = XEXP (DECL_RTL (function), 0);
20602 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20605 if (MACHOPIC_INDIRECT)
20606 funexp = machopic_indirect_call_target (funexp);
20609 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20610 generate sibcall RTL explicitly. */
20611 insn = emit_call_insn (
20612 gen_rtx_PARALLEL (VOIDmode,
20614 gen_rtx_CALL (VOIDmode,
20615 funexp, const0_rtx),
20616 gen_rtx_USE (VOIDmode, const0_rtx),
20617 gen_rtx_USE (VOIDmode,
20618 gen_rtx_REG (SImode,
20620 gen_rtx_RETURN (VOIDmode))));
20621 SIBLING_CALL_P (insn) = 1;
20624 /* Run just enough of rest_of_compilation to get the insns emitted.
20625 There's not really enough bulk here to make other passes such as
20626 instruction scheduling worth while. Note that use_thunk calls
20627 assemble_start_function and assemble_end_function. */
20628 insn = get_insns ();
20629 insn_locators_alloc ();
20630 shorten_branches (insn);
20631 final_start_function (insn, file, 1);
20632 final (insn, file, 1);
20633 final_end_function ();
20635 reload_completed = 0;
20636 epilogue_completed = 0;
20639 /* A quick summary of the various types of 'constant-pool tables'
20642 Target Flags Name One table per
20643 AIX (none) AIX TOC object file
20644 AIX -mfull-toc AIX TOC object file
20645 AIX -mminimal-toc AIX minimal TOC translation unit
20646 SVR4/EABI (none) SVR4 SDATA object file
20647 SVR4/EABI -fpic SVR4 pic object file
20648 SVR4/EABI -fPIC SVR4 PIC translation unit
20649 SVR4/EABI -mrelocatable EABI TOC function
20650 SVR4/EABI -maix AIX TOC object file
20651 SVR4/EABI -maix -mminimal-toc
20652 AIX minimal TOC translation unit
20654 Name Reg. Set by entries contains:
20655 made by addrs? fp? sum?
20657 AIX TOC 2 crt0 as Y option option
20658 AIX minimal TOC 30 prolog gcc Y Y option
20659 SVR4 SDATA 13 crt0 gcc N Y N
20660 SVR4 pic 30 prolog ld Y not yet N
20661 SVR4 PIC 30 prolog gcc Y option option
20662 EABI TOC 30 prolog gcc Y option option
20666 /* Hash functions for the hash table. */
20669 rs6000_hash_constant (rtx k)
20671 enum rtx_code code = GET_CODE (k);
20672 enum machine_mode mode = GET_MODE (k);
20673 unsigned result = (code << 3) ^ mode;
20674 const char *format;
20677 format = GET_RTX_FORMAT (code);
20678 flen = strlen (format);
20684 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20687 if (mode != VOIDmode)
20688 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20700 for (; fidx < flen; fidx++)
20701 switch (format[fidx])
20706 const char *str = XSTR (k, fidx);
20707 len = strlen (str);
20708 result = result * 613 + len;
20709 for (i = 0; i < len; i++)
20710 result = result * 613 + (unsigned) str[i];
20715 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20719 result = result * 613 + (unsigned) XINT (k, fidx);
20722 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20723 result = result * 613 + (unsigned) XWINT (k, fidx);
20727 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20728 result = result * 613 + (unsigned) (XWINT (k, fidx)
20735 gcc_unreachable ();
20742 toc_hash_function (const void *hash_entry)
20744 const struct toc_hash_struct *thc =
20745 (const struct toc_hash_struct *) hash_entry;
20746 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20749 /* Compare H1 and H2 for equivalence. */
20752 toc_hash_eq (const void *h1, const void *h2)
20754 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20755 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20757 if (((const struct toc_hash_struct *) h1)->key_mode
20758 != ((const struct toc_hash_struct *) h2)->key_mode)
20761 return rtx_equal_p (r1, r2);
20764 /* These are the names given by the C++ front-end to vtables, and
20765 vtable-like objects. Ideally, this logic should not be here;
20766 instead, there should be some programmatic way of inquiring as
20767 to whether or not an object is a vtable. */
20769 #define VTABLE_NAME_P(NAME) \
20770 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20771 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20772 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20773 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20774 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20776 #ifdef NO_DOLLAR_IN_LABEL
20777 /* Return a GGC-allocated character string translating dollar signs in
20778 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20781 rs6000_xcoff_strip_dollar (const char *name)
20786 p = strchr (name, '$');
20788 if (p == 0 || p == name)
20791 len = strlen (name);
20792 strip = (char *) alloca (len + 1);
20793 strcpy (strip, name);
20794 p = strchr (strip, '$');
20798 p = strchr (p + 1, '$');
20801 return ggc_alloc_string (strip, len);
20806 rs6000_output_symbol_ref (FILE *file, rtx x)
20808 /* Currently C++ toc references to vtables can be emitted before it
20809 is decided whether the vtable is public or private. If this is
20810 the case, then the linker will eventually complain that there is
20811 a reference to an unknown section. Thus, for vtables only,
20812 we emit the TOC reference to reference the symbol and not the
20814 const char *name = XSTR (x, 0);
20816 if (VTABLE_NAME_P (name))
20818 RS6000_OUTPUT_BASENAME (file, name);
20821 assemble_name (file, name);
20824 /* Output a TOC entry. We derive the entry name from what is being
20828 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20831 const char *name = buf;
20833 HOST_WIDE_INT offset = 0;
20835 gcc_assert (!TARGET_NO_TOC);
20837 /* When the linker won't eliminate them, don't output duplicate
20838 TOC entries (this happens on AIX if there is any kind of TOC,
20839 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20841 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20843 struct toc_hash_struct *h;
20846 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20847 time because GGC is not initialized at that point. */
20848 if (toc_hash_table == NULL)
20849 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20850 toc_hash_eq, NULL);
20852 h = GGC_NEW (struct toc_hash_struct);
20854 h->key_mode = mode;
20855 h->labelno = labelno;
20857 found = htab_find_slot (toc_hash_table, h, INSERT);
20858 if (*found == NULL)
20860 else /* This is indeed a duplicate.
20861 Set this label equal to that label. */
20863 fputs ("\t.set ", file);
20864 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20865 fprintf (file, "%d,", labelno);
20866 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20867 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20873 /* If we're going to put a double constant in the TOC, make sure it's
20874 aligned properly when strict alignment is on. */
20875 if (GET_CODE (x) == CONST_DOUBLE
20876 && STRICT_ALIGNMENT
20877 && GET_MODE_BITSIZE (mode) >= 64
20878 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20879 ASM_OUTPUT_ALIGN (file, 3);
20882 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20884 /* Handle FP constants specially. Note that if we have a minimal
20885 TOC, things we put here aren't actually in the TOC, so we can allow
20887 if (GET_CODE (x) == CONST_DOUBLE &&
20888 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20890 REAL_VALUE_TYPE rv;
20893 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20894 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20895 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20897 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20901 if (TARGET_MINIMAL_TOC)
20902 fputs (DOUBLE_INT_ASM_OP, file);
20904 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20905 k[0] & 0xffffffff, k[1] & 0xffffffff,
20906 k[2] & 0xffffffff, k[3] & 0xffffffff);
20907 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20908 k[0] & 0xffffffff, k[1] & 0xffffffff,
20909 k[2] & 0xffffffff, k[3] & 0xffffffff);
20914 if (TARGET_MINIMAL_TOC)
20915 fputs ("\t.long ", file);
20917 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20918 k[0] & 0xffffffff, k[1] & 0xffffffff,
20919 k[2] & 0xffffffff, k[3] & 0xffffffff);
20920 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20921 k[0] & 0xffffffff, k[1] & 0xffffffff,
20922 k[2] & 0xffffffff, k[3] & 0xffffffff);
20926 else if (GET_CODE (x) == CONST_DOUBLE &&
20927 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20929 REAL_VALUE_TYPE rv;
20932 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20934 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20935 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20937 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20941 if (TARGET_MINIMAL_TOC)
20942 fputs (DOUBLE_INT_ASM_OP, file);
20944 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20945 k[0] & 0xffffffff, k[1] & 0xffffffff);
20946 fprintf (file, "0x%lx%08lx\n",
20947 k[0] & 0xffffffff, k[1] & 0xffffffff);
20952 if (TARGET_MINIMAL_TOC)
20953 fputs ("\t.long ", file);
20955 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20956 k[0] & 0xffffffff, k[1] & 0xffffffff);
20957 fprintf (file, "0x%lx,0x%lx\n",
20958 k[0] & 0xffffffff, k[1] & 0xffffffff);
20962 else if (GET_CODE (x) == CONST_DOUBLE &&
20963 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20965 REAL_VALUE_TYPE rv;
20968 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20969 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20970 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20972 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20976 if (TARGET_MINIMAL_TOC)
20977 fputs (DOUBLE_INT_ASM_OP, file);
20979 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20980 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20985 if (TARGET_MINIMAL_TOC)
20986 fputs ("\t.long ", file);
20988 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20989 fprintf (file, "0x%lx\n", l & 0xffffffff);
20993 else if (GET_MODE (x) == VOIDmode
20994 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20996 unsigned HOST_WIDE_INT low;
20997 HOST_WIDE_INT high;
20999 if (GET_CODE (x) == CONST_DOUBLE)
21001 low = CONST_DOUBLE_LOW (x);
21002 high = CONST_DOUBLE_HIGH (x);
21005 #if HOST_BITS_PER_WIDE_INT == 32
21008 high = (low & 0x80000000) ? ~0 : 0;
21012 low = INTVAL (x) & 0xffffffff;
21013 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21017 /* TOC entries are always Pmode-sized, but since this
21018 is a bigendian machine then if we're putting smaller
21019 integer constants in the TOC we have to pad them.
21020 (This is still a win over putting the constants in
21021 a separate constant pool, because then we'd have
21022 to have both a TOC entry _and_ the actual constant.)
21024 For a 32-bit target, CONST_INT values are loaded and shifted
21025 entirely within `low' and can be stored in one TOC entry. */
21027 /* It would be easy to make this work, but it doesn't now. */
21028 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21030 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21032 #if HOST_BITS_PER_WIDE_INT == 32
21033 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21034 POINTER_SIZE, &low, &high, 0);
21037 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21038 high = (HOST_WIDE_INT) low >> 32;
21045 if (TARGET_MINIMAL_TOC)
21046 fputs (DOUBLE_INT_ASM_OP, file);
21048 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21049 (long) high & 0xffffffff, (long) low & 0xffffffff);
21050 fprintf (file, "0x%lx%08lx\n",
21051 (long) high & 0xffffffff, (long) low & 0xffffffff);
21056 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21058 if (TARGET_MINIMAL_TOC)
21059 fputs ("\t.long ", file);
21061 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21062 (long) high & 0xffffffff, (long) low & 0xffffffff);
21063 fprintf (file, "0x%lx,0x%lx\n",
21064 (long) high & 0xffffffff, (long) low & 0xffffffff);
21068 if (TARGET_MINIMAL_TOC)
21069 fputs ("\t.long ", file);
21071 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21072 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21078 if (GET_CODE (x) == CONST)
21080 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21081 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21083 base = XEXP (XEXP (x, 0), 0);
21084 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21087 switch (GET_CODE (base))
21090 name = XSTR (base, 0);
21094 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21095 CODE_LABEL_NUMBER (XEXP (base, 0)));
21099 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21103 gcc_unreachable ();
21106 if (TARGET_MINIMAL_TOC)
21107 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21110 fputs ("\t.tc ", file);
21111 RS6000_OUTPUT_BASENAME (file, name);
21114 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21116 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21118 fputs ("[TC],", file);
21121 /* Currently C++ toc references to vtables can be emitted before it
21122 is decided whether the vtable is public or private. If this is
21123 the case, then the linker will eventually complain that there is
21124 a TOC reference to an unknown section. Thus, for vtables only,
21125 we emit the TOC reference to reference the symbol and not the
21127 if (VTABLE_NAME_P (name))
21129 RS6000_OUTPUT_BASENAME (file, name);
21131 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21132 else if (offset > 0)
21133 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21136 output_addr_const (file, x);
21140 /* Output an assembler pseudo-op to write an ASCII string of N characters
21141 starting at P to FILE.
21143 On the RS/6000, we have to do this using the .byte operation and
21144 write out special characters outside the quoted string.
21145 Also, the assembler is broken; very long strings are truncated,
21146 so we must artificially break them up early. */
21149 output_ascii (FILE *file, const char *p, int n)
21152 int i, count_string;
21153 const char *for_string = "\t.byte \"";
21154 const char *for_decimal = "\t.byte ";
21155 const char *to_close = NULL;
21158 for (i = 0; i < n; i++)
21161 if (c >= ' ' && c < 0177)
21164 fputs (for_string, file);
21167 /* Write two quotes to get one. */
21175 for_decimal = "\"\n\t.byte ";
21179 if (count_string >= 512)
21181 fputs (to_close, file);
21183 for_string = "\t.byte \"";
21184 for_decimal = "\t.byte ";
21192 fputs (for_decimal, file);
21193 fprintf (file, "%d", c);
21195 for_string = "\n\t.byte \"";
21196 for_decimal = ", ";
21202 /* Now close the string if we have written one. Then end the line. */
21204 fputs (to_close, file);
21207 /* Generate a unique section name for FILENAME for a section type
21208 represented by SECTION_DESC. Output goes into BUF.
21210 SECTION_DESC can be any string, as long as it is different for each
21211 possible section type.
21213 We name the section in the same manner as xlc. The name begins with an
21214 underscore followed by the filename (after stripping any leading directory
21215 names) with the last period replaced by the string SECTION_DESC. If
21216 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21220 rs6000_gen_section_name (char **buf, const char *filename,
21221 const char *section_desc)
21223 const char *q, *after_last_slash, *last_period = 0;
21227 after_last_slash = filename;
21228 for (q = filename; *q; q++)
21231 after_last_slash = q + 1;
21232 else if (*q == '.')
21236 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21237 *buf = (char *) xmalloc (len);
21242 for (q = after_last_slash; *q; q++)
21244 if (q == last_period)
21246 strcpy (p, section_desc);
21247 p += strlen (section_desc);
21251 else if (ISALNUM (*q))
21255 if (last_period == 0)
21256 strcpy (p, section_desc);
21261 /* Emit profile function. */
21264 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21266 /* Non-standard profiling for kernels, which just saves LR then calls
21267 _mcount without worrying about arg saves. The idea is to change
21268 the function prologue as little as possible as it isn't easy to
21269 account for arg save/restore code added just for _mcount. */
21270 if (TARGET_PROFILE_KERNEL)
21273 if (DEFAULT_ABI == ABI_AIX)
21275 #ifndef NO_PROFILE_COUNTERS
21276 # define NO_PROFILE_COUNTERS 0
21278 if (NO_PROFILE_COUNTERS)
21279 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21280 LCT_NORMAL, VOIDmode, 0);
21284 const char *label_name;
21287 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21288 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21289 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21291 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21292 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21295 else if (DEFAULT_ABI == ABI_DARWIN)
21297 const char *mcount_name = RS6000_MCOUNT;
21298 int caller_addr_regno = LR_REGNO;
21300 /* Be conservative and always set this, at least for now. */
21301 crtl->uses_pic_offset_table = 1;
21304 /* For PIC code, set up a stub and collect the caller's address
21305 from r0, which is where the prologue puts it. */
21306 if (MACHOPIC_INDIRECT
21307 && crtl->uses_pic_offset_table)
21308 caller_addr_regno = 0;
21310 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21311 LCT_NORMAL, VOIDmode, 1,
21312 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21316 /* Write function profiler code. */
21319 output_function_profiler (FILE *file, int labelno)
21323 switch (DEFAULT_ABI)
21326 gcc_unreachable ();
21331 warning (0, "no profiling of 64-bit code for this ABI");
21334 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21335 fprintf (file, "\tmflr %s\n", reg_names[0]);
21336 if (NO_PROFILE_COUNTERS)
21338 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21339 reg_names[0], reg_names[1]);
21341 else if (TARGET_SECURE_PLT && flag_pic)
21343 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21344 reg_names[0], reg_names[1]);
21345 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21346 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21347 reg_names[12], reg_names[12]);
21348 assemble_name (file, buf);
21349 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21350 assemble_name (file, buf);
21351 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21353 else if (flag_pic == 1)
21355 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21356 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21357 reg_names[0], reg_names[1]);
21358 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21359 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21360 assemble_name (file, buf);
21361 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21363 else if (flag_pic > 1)
21365 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21366 reg_names[0], reg_names[1]);
21367 /* Now, we need to get the address of the label. */
21368 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21369 assemble_name (file, buf);
21370 fputs ("-.\n1:", file);
21371 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21372 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21373 reg_names[0], reg_names[11]);
21374 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21375 reg_names[0], reg_names[0], reg_names[11]);
21379 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21380 assemble_name (file, buf);
21381 fputs ("@ha\n", file);
21382 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21383 reg_names[0], reg_names[1]);
21384 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21385 assemble_name (file, buf);
21386 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21389 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21390 fprintf (file, "\tbl %s%s\n",
21391 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21396 if (!TARGET_PROFILE_KERNEL)
21398 /* Don't do anything, done in output_profile_hook (). */
21402 gcc_assert (!TARGET_32BIT);
21404 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21405 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21407 if (cfun->static_chain_decl != NULL)
21409 asm_fprintf (file, "\tstd %s,24(%s)\n",
21410 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21411 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21412 asm_fprintf (file, "\tld %s,24(%s)\n",
21413 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21416 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21424 /* The following variable value is the last issued insn. */
21426 static rtx last_scheduled_insn;
21428 /* The following variable helps to balance issuing of load and
21429 store instructions */
21431 static int load_store_pendulum;
21433 /* Power4 load update and store update instructions are cracked into a
21434 load or store and an integer insn which are executed in the same cycle.
21435 Branches have their own dispatch slot which does not count against the
21436 GCC issue rate, but it changes the program flow so there are no other
21437 instructions to issue in this cycle. */
21440 rs6000_variable_issue_1 (rtx insn, int more)
21442 last_scheduled_insn = insn;
21443 if (GET_CODE (PATTERN (insn)) == USE
21444 || GET_CODE (PATTERN (insn)) == CLOBBER)
21446 cached_can_issue_more = more;
21447 return cached_can_issue_more;
21450 if (insn_terminates_group_p (insn, current_group))
21452 cached_can_issue_more = 0;
21453 return cached_can_issue_more;
21456 /* If no reservation, but reach here */
21457 if (recog_memoized (insn) < 0)
21460 if (rs6000_sched_groups)
21462 if (is_microcoded_insn (insn))
21463 cached_can_issue_more = 0;
21464 else if (is_cracked_insn (insn))
21465 cached_can_issue_more = more > 2 ? more - 2 : 0;
21467 cached_can_issue_more = more - 1;
21469 return cached_can_issue_more;
21472 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21475 cached_can_issue_more = more - 1;
21476 return cached_can_issue_more;
21480 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21482 int r = rs6000_variable_issue_1 (insn, more);
21484 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21488 /* Adjust the cost of a scheduling dependency. Return the new cost of
21489 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21492 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21494 enum attr_type attr_type;
21496 if (! recog_memoized (insn))
21499 switch (REG_NOTE_KIND (link))
21503 /* Data dependency; DEP_INSN writes a register that INSN reads
21504 some cycles later. */
21506 /* Separate a load from a narrower, dependent store. */
21507 if (rs6000_sched_groups
21508 && GET_CODE (PATTERN (insn)) == SET
21509 && GET_CODE (PATTERN (dep_insn)) == SET
21510 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21511 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21512 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21513 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21516 attr_type = get_attr_type (insn);
21521 /* Tell the first scheduling pass about the latency between
21522 a mtctr and bctr (and mtlr and br/blr). The first
21523 scheduling pass will not know about this latency since
21524 the mtctr instruction, which has the latency associated
21525 to it, will be generated by reload. */
21526 return TARGET_POWER ? 5 : 4;
21528 /* Leave some extra cycles between a compare and its
21529 dependent branch, to inhibit expensive mispredicts. */
21530 if ((rs6000_cpu_attr == CPU_PPC603
21531 || rs6000_cpu_attr == CPU_PPC604
21532 || rs6000_cpu_attr == CPU_PPC604E
21533 || rs6000_cpu_attr == CPU_PPC620
21534 || rs6000_cpu_attr == CPU_PPC630
21535 || rs6000_cpu_attr == CPU_PPC750
21536 || rs6000_cpu_attr == CPU_PPC7400
21537 || rs6000_cpu_attr == CPU_PPC7450
21538 || rs6000_cpu_attr == CPU_POWER4
21539 || rs6000_cpu_attr == CPU_POWER5
21540 || rs6000_cpu_attr == CPU_POWER7
21541 || rs6000_cpu_attr == CPU_CELL)
21542 && recog_memoized (dep_insn)
21543 && (INSN_CODE (dep_insn) >= 0))
21545 switch (get_attr_type (dep_insn))
21549 case TYPE_DELAYED_COMPARE:
21550 case TYPE_IMUL_COMPARE:
21551 case TYPE_LMUL_COMPARE:
21552 case TYPE_FPCOMPARE:
21553 case TYPE_CR_LOGICAL:
21554 case TYPE_DELAYED_CR:
21563 case TYPE_STORE_UX:
21565 case TYPE_FPSTORE_U:
21566 case TYPE_FPSTORE_UX:
21567 if ((rs6000_cpu == PROCESSOR_POWER6)
21568 && recog_memoized (dep_insn)
21569 && (INSN_CODE (dep_insn) >= 0))
21572 if (GET_CODE (PATTERN (insn)) != SET)
21573 /* If this happens, we have to extend this to schedule
21574 optimally. Return default for now. */
21577 /* Adjust the cost for the case where the value written
21578 by a fixed point operation is used as the address
21579 gen value on a store. */
21580 switch (get_attr_type (dep_insn))
21587 if (! store_data_bypass_p (dep_insn, insn))
21591 case TYPE_LOAD_EXT:
21592 case TYPE_LOAD_EXT_U:
21593 case TYPE_LOAD_EXT_UX:
21594 case TYPE_VAR_SHIFT_ROTATE:
21595 case TYPE_VAR_DELAYED_COMPARE:
21597 if (! store_data_bypass_p (dep_insn, insn))
21603 case TYPE_FAST_COMPARE:
21606 case TYPE_INSERT_WORD:
21607 case TYPE_INSERT_DWORD:
21608 case TYPE_FPLOAD_U:
21609 case TYPE_FPLOAD_UX:
21611 case TYPE_STORE_UX:
21612 case TYPE_FPSTORE_U:
21613 case TYPE_FPSTORE_UX:
21615 if (! store_data_bypass_p (dep_insn, insn))
21623 case TYPE_IMUL_COMPARE:
21624 case TYPE_LMUL_COMPARE:
21626 if (! store_data_bypass_p (dep_insn, insn))
21632 if (! store_data_bypass_p (dep_insn, insn))
21638 if (! store_data_bypass_p (dep_insn, insn))
21651 case TYPE_LOAD_EXT:
21652 case TYPE_LOAD_EXT_U:
21653 case TYPE_LOAD_EXT_UX:
21654 if ((rs6000_cpu == PROCESSOR_POWER6)
21655 && recog_memoized (dep_insn)
21656 && (INSN_CODE (dep_insn) >= 0))
21659 /* Adjust the cost for the case where the value written
21660 by a fixed point instruction is used within the address
21661 gen portion of a subsequent load(u)(x) */
21662 switch (get_attr_type (dep_insn))
21669 if (set_to_load_agen (dep_insn, insn))
21673 case TYPE_LOAD_EXT:
21674 case TYPE_LOAD_EXT_U:
21675 case TYPE_LOAD_EXT_UX:
21676 case TYPE_VAR_SHIFT_ROTATE:
21677 case TYPE_VAR_DELAYED_COMPARE:
21679 if (set_to_load_agen (dep_insn, insn))
21685 case TYPE_FAST_COMPARE:
21688 case TYPE_INSERT_WORD:
21689 case TYPE_INSERT_DWORD:
21690 case TYPE_FPLOAD_U:
21691 case TYPE_FPLOAD_UX:
21693 case TYPE_STORE_UX:
21694 case TYPE_FPSTORE_U:
21695 case TYPE_FPSTORE_UX:
21697 if (set_to_load_agen (dep_insn, insn))
21705 case TYPE_IMUL_COMPARE:
21706 case TYPE_LMUL_COMPARE:
21708 if (set_to_load_agen (dep_insn, insn))
21714 if (set_to_load_agen (dep_insn, insn))
21720 if (set_to_load_agen (dep_insn, insn))
21731 if ((rs6000_cpu == PROCESSOR_POWER6)
21732 && recog_memoized (dep_insn)
21733 && (INSN_CODE (dep_insn) >= 0)
21734 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21741 /* Fall out to return default cost. */
21745 case REG_DEP_OUTPUT:
21746 /* Output dependency; DEP_INSN writes a register that INSN writes some
21748 if ((rs6000_cpu == PROCESSOR_POWER6)
21749 && recog_memoized (dep_insn)
21750 && (INSN_CODE (dep_insn) >= 0))
21752 attr_type = get_attr_type (insn);
21757 if (get_attr_type (dep_insn) == TYPE_FP)
21761 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21769 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21774 gcc_unreachable ();
21780 /* Debug version of rs6000_adjust_cost. */
21783 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21785 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21791 switch (REG_NOTE_KIND (link))
21793 default: dep = "unknown depencency"; break;
21794 case REG_DEP_TRUE: dep = "data dependency"; break;
21795 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21796 case REG_DEP_ANTI: dep = "anti depencency"; break;
21800 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21801 "%s, insn:\n", ret, cost, dep);
21809 /* The function returns a true if INSN is microcoded.
21810 Return false otherwise. */
21813 is_microcoded_insn (rtx insn)
21815 if (!insn || !NONDEBUG_INSN_P (insn)
21816 || GET_CODE (PATTERN (insn)) == USE
21817 || GET_CODE (PATTERN (insn)) == CLOBBER)
21820 if (rs6000_cpu_attr == CPU_CELL)
21821 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21823 if (rs6000_sched_groups)
21825 enum attr_type type = get_attr_type (insn);
21826 if (type == TYPE_LOAD_EXT_U
21827 || type == TYPE_LOAD_EXT_UX
21828 || type == TYPE_LOAD_UX
21829 || type == TYPE_STORE_UX
21830 || type == TYPE_MFCR)
21837 /* The function returns true if INSN is cracked into 2 instructions
21838 by the processor (and therefore occupies 2 issue slots). */
21841 is_cracked_insn (rtx insn)
21843 if (!insn || !NONDEBUG_INSN_P (insn)
21844 || GET_CODE (PATTERN (insn)) == USE
21845 || GET_CODE (PATTERN (insn)) == CLOBBER)
21848 if (rs6000_sched_groups)
21850 enum attr_type type = get_attr_type (insn);
21851 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21852 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21853 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21854 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21855 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21856 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21857 || type == TYPE_IDIV || type == TYPE_LDIV
21858 || type == TYPE_INSERT_WORD)
21865 /* The function returns true if INSN can be issued only from
21866 the branch slot. */
21869 is_branch_slot_insn (rtx insn)
21871 if (!insn || !NONDEBUG_INSN_P (insn)
21872 || GET_CODE (PATTERN (insn)) == USE
21873 || GET_CODE (PATTERN (insn)) == CLOBBER)
21876 if (rs6000_sched_groups)
21878 enum attr_type type = get_attr_type (insn);
21879 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21887 /* The function returns true if out_inst sets a value that is
21888 used in the address generation computation of in_insn */
21890 set_to_load_agen (rtx out_insn, rtx in_insn)
21892 rtx out_set, in_set;
21894 /* For performance reasons, only handle the simple case where
21895 both loads are a single_set. */
21896 out_set = single_set (out_insn);
21899 in_set = single_set (in_insn);
21901 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21907 /* The function returns true if the target storage location of
21908 out_insn is adjacent to the target storage location of in_insn */
21909 /* Return 1 if memory locations are adjacent. */
21912 adjacent_mem_locations (rtx insn1, rtx insn2)
21915 rtx a = get_store_dest (PATTERN (insn1));
21916 rtx b = get_store_dest (PATTERN (insn2));
21918 if ((GET_CODE (XEXP (a, 0)) == REG
21919 || (GET_CODE (XEXP (a, 0)) == PLUS
21920 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21921 && (GET_CODE (XEXP (b, 0)) == REG
21922 || (GET_CODE (XEXP (b, 0)) == PLUS
21923 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21925 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21928 if (GET_CODE (XEXP (a, 0)) == PLUS)
21930 reg0 = XEXP (XEXP (a, 0), 0);
21931 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21934 reg0 = XEXP (a, 0);
21936 if (GET_CODE (XEXP (b, 0)) == PLUS)
21938 reg1 = XEXP (XEXP (b, 0), 0);
21939 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21942 reg1 = XEXP (b, 0);
21944 val_diff = val1 - val0;
21946 return ((REGNO (reg0) == REGNO (reg1))
21947 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21948 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21954 /* A C statement (sans semicolon) to update the integer scheduling
21955 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21956 INSN earlier, reduce the priority to execute INSN later. Do not
21957 define this macro if you do not need to adjust the scheduling
21958 priorities of insns. */
21961 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21963 /* On machines (like the 750) which have asymmetric integer units,
21964 where one integer unit can do multiply and divides and the other
21965 can't, reduce the priority of multiply/divide so it is scheduled
21966 before other integer operations. */
21969 if (! INSN_P (insn))
21972 if (GET_CODE (PATTERN (insn)) == USE)
21975 switch (rs6000_cpu_attr) {
21977 switch (get_attr_type (insn))
21984 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21985 priority, priority);
21986 if (priority >= 0 && priority < 0x01000000)
21993 if (insn_must_be_first_in_group (insn)
21994 && reload_completed
21995 && current_sched_info->sched_max_insns_priority
21996 && rs6000_sched_restricted_insns_priority)
21999 /* Prioritize insns that can be dispatched only in the first
22001 if (rs6000_sched_restricted_insns_priority == 1)
22002 /* Attach highest priority to insn. This means that in
22003 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22004 precede 'priority' (critical path) considerations. */
22005 return current_sched_info->sched_max_insns_priority;
22006 else if (rs6000_sched_restricted_insns_priority == 2)
22007 /* Increase priority of insn by a minimal amount. This means that in
22008 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22009 considerations precede dispatch-slot restriction considerations. */
22010 return (priority + 1);
22013 if (rs6000_cpu == PROCESSOR_POWER6
22014 && ((load_store_pendulum == -2 && is_load_insn (insn))
22015 || (load_store_pendulum == 2 && is_store_insn (insn))))
22016 /* Attach highest priority to insn if the scheduler has just issued two
22017 stores and this instruction is a load, or two loads and this instruction
22018 is a store. Power6 wants loads and stores scheduled alternately
22020 return current_sched_info->sched_max_insns_priority;
22025 /* Return true if the instruction is nonpipelined on the Cell. */
22027 is_nonpipeline_insn (rtx insn)
22029 enum attr_type type;
22030 if (!insn || !NONDEBUG_INSN_P (insn)
22031 || GET_CODE (PATTERN (insn)) == USE
22032 || GET_CODE (PATTERN (insn)) == CLOBBER)
22035 type = get_attr_type (insn);
22036 if (type == TYPE_IMUL
22037 || type == TYPE_IMUL2
22038 || type == TYPE_IMUL3
22039 || type == TYPE_LMUL
22040 || type == TYPE_IDIV
22041 || type == TYPE_LDIV
22042 || type == TYPE_SDIV
22043 || type == TYPE_DDIV
22044 || type == TYPE_SSQRT
22045 || type == TYPE_DSQRT
22046 || type == TYPE_MFCR
22047 || type == TYPE_MFCRF
22048 || type == TYPE_MFJMPR)
22056 /* Return how many instructions the machine can issue per cycle. */
22059 rs6000_issue_rate (void)
22061 /* Unless scheduling for register pressure, use issue rate of 1 for
22062 first scheduling pass to decrease degradation. */
22063 if (!reload_completed && !flag_sched_pressure)
22066 switch (rs6000_cpu_attr) {
22067 case CPU_RIOS1: /* ? */
22069 case CPU_PPC601: /* ? */
22078 case CPU_PPCE300C2:
22079 case CPU_PPCE300C3:
22080 case CPU_PPCE500MC:
22081 case CPU_PPCE500MC64:
22100 /* Return how many instructions to look ahead for better insn
22104 rs6000_use_sched_lookahead (void)
22106 if (rs6000_cpu_attr == CPU_PPC8540)
22108 if (rs6000_cpu_attr == CPU_CELL)
22109 return (reload_completed ? 8 : 0);
22113 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22115 rs6000_use_sched_lookahead_guard (rtx insn)
22117 if (rs6000_cpu_attr != CPU_CELL)
22120 if (insn == NULL_RTX || !INSN_P (insn))
22123 if (!reload_completed
22124 || is_nonpipeline_insn (insn)
22125 || is_microcoded_insn (insn))
22131 /* Determine is PAT refers to memory. */
22134 is_mem_ref (rtx pat)
22140 /* stack_tie does not produce any real memory traffic. */
22141 if (GET_CODE (pat) == UNSPEC
22142 && XINT (pat, 1) == UNSPEC_TIE)
22145 if (GET_CODE (pat) == MEM)
22148 /* Recursively process the pattern. */
22149 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22151 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22154 ret |= is_mem_ref (XEXP (pat, i));
22155 else if (fmt[i] == 'E')
22156 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22157 ret |= is_mem_ref (XVECEXP (pat, i, j));
22163 /* Determine if PAT is a PATTERN of a load insn. */
22166 is_load_insn1 (rtx pat)
22168 if (!pat || pat == NULL_RTX)
22171 if (GET_CODE (pat) == SET)
22172 return is_mem_ref (SET_SRC (pat));
22174 if (GET_CODE (pat) == PARALLEL)
22178 for (i = 0; i < XVECLEN (pat, 0); i++)
22179 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22186 /* Determine if INSN loads from memory. */
22189 is_load_insn (rtx insn)
22191 if (!insn || !INSN_P (insn))
22194 if (GET_CODE (insn) == CALL_INSN)
22197 return is_load_insn1 (PATTERN (insn));
22200 /* Determine if PAT is a PATTERN of a store insn. */
22203 is_store_insn1 (rtx pat)
22205 if (!pat || pat == NULL_RTX)
22208 if (GET_CODE (pat) == SET)
22209 return is_mem_ref (SET_DEST (pat));
22211 if (GET_CODE (pat) == PARALLEL)
22215 for (i = 0; i < XVECLEN (pat, 0); i++)
22216 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22223 /* Determine if INSN stores to memory. */
22226 is_store_insn (rtx insn)
22228 if (!insn || !INSN_P (insn))
22231 return is_store_insn1 (PATTERN (insn));
22234 /* Return the dest of a store insn. */
22237 get_store_dest (rtx pat)
22239 gcc_assert (is_store_insn1 (pat));
22241 if (GET_CODE (pat) == SET)
22242 return SET_DEST (pat);
22243 else if (GET_CODE (pat) == PARALLEL)
22247 for (i = 0; i < XVECLEN (pat, 0); i++)
22249 rtx inner_pat = XVECEXP (pat, 0, i);
22250 if (GET_CODE (inner_pat) == SET
22251 && is_mem_ref (SET_DEST (inner_pat)))
22255 /* We shouldn't get here, because we should have either a simple
22256 store insn or a store with update which are covered above. */
22260 /* Returns whether the dependence between INSN and NEXT is considered
22261 costly by the given target. */
22264 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22269 /* If the flag is not enabled - no dependence is considered costly;
22270 allow all dependent insns in the same group.
22271 This is the most aggressive option. */
22272 if (rs6000_sched_costly_dep == no_dep_costly)
22275 /* If the flag is set to 1 - a dependence is always considered costly;
22276 do not allow dependent instructions in the same group.
22277 This is the most conservative option. */
22278 if (rs6000_sched_costly_dep == all_deps_costly)
22281 insn = DEP_PRO (dep);
22282 next = DEP_CON (dep);
22284 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22285 && is_load_insn (next)
22286 && is_store_insn (insn))
22287 /* Prevent load after store in the same group. */
22290 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22291 && is_load_insn (next)
22292 && is_store_insn (insn)
22293 && DEP_TYPE (dep) == REG_DEP_TRUE)
22294 /* Prevent load after store in the same group if it is a true
22298 /* The flag is set to X; dependences with latency >= X are considered costly,
22299 and will not be scheduled in the same group. */
22300 if (rs6000_sched_costly_dep <= max_dep_latency
22301 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22307 /* Return the next insn after INSN that is found before TAIL is reached,
22308 skipping any "non-active" insns - insns that will not actually occupy
22309 an issue slot. Return NULL_RTX if such an insn is not found. */
22312 get_next_active_insn (rtx insn, rtx tail)
22314 if (insn == NULL_RTX || insn == tail)
22319 insn = NEXT_INSN (insn);
22320 if (insn == NULL_RTX || insn == tail)
22325 || (NONJUMP_INSN_P (insn)
22326 && GET_CODE (PATTERN (insn)) != USE
22327 && GET_CODE (PATTERN (insn)) != CLOBBER
22328 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22334 /* We are about to begin issuing insns for this clock cycle. */
22337 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22338 rtx *ready ATTRIBUTE_UNUSED,
22339 int *pn_ready ATTRIBUTE_UNUSED,
22340 int clock_var ATTRIBUTE_UNUSED)
22342 int n_ready = *pn_ready;
22345 fprintf (dump, "// rs6000_sched_reorder :\n");
22347 /* Reorder the ready list, if the second to last ready insn
22348 is a nonepipeline insn. */
22349 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22351 if (is_nonpipeline_insn (ready[n_ready - 1])
22352 && (recog_memoized (ready[n_ready - 2]) > 0))
22353 /* Simply swap first two insns. */
22355 rtx tmp = ready[n_ready - 1];
22356 ready[n_ready - 1] = ready[n_ready - 2];
22357 ready[n_ready - 2] = tmp;
22361 if (rs6000_cpu == PROCESSOR_POWER6)
22362 load_store_pendulum = 0;
22364 return rs6000_issue_rate ();
22367 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22370 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22371 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22374 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22376 /* For Power6, we need to handle some special cases to try and keep the
22377 store queue from overflowing and triggering expensive flushes.
22379 This code monitors how load and store instructions are being issued
22380 and skews the ready list one way or the other to increase the likelihood
22381 that a desired instruction is issued at the proper time.
22383 A couple of things are done. First, we maintain a "load_store_pendulum"
22384 to track the current state of load/store issue.
22386 - If the pendulum is at zero, then no loads or stores have been
22387 issued in the current cycle so we do nothing.
22389 - If the pendulum is 1, then a single load has been issued in this
22390 cycle and we attempt to locate another load in the ready list to
22393 - If the pendulum is -2, then two stores have already been
22394 issued in this cycle, so we increase the priority of the first load
22395 in the ready list to increase it's likelihood of being chosen first
22398 - If the pendulum is -1, then a single store has been issued in this
22399 cycle and we attempt to locate another store in the ready list to
22400 issue with it, preferring a store to an adjacent memory location to
22401 facilitate store pairing in the store queue.
22403 - If the pendulum is 2, then two loads have already been
22404 issued in this cycle, so we increase the priority of the first store
22405 in the ready list to increase it's likelihood of being chosen first
22408 - If the pendulum < -2 or > 2, then do nothing.
22410 Note: This code covers the most common scenarios. There exist non
22411 load/store instructions which make use of the LSU and which
22412 would need to be accounted for to strictly model the behavior
22413 of the machine. Those instructions are currently unaccounted
22414 for to help minimize compile time overhead of this code.
22416 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22422 if (is_store_insn (last_scheduled_insn))
22423 /* Issuing a store, swing the load_store_pendulum to the left */
22424 load_store_pendulum--;
22425 else if (is_load_insn (last_scheduled_insn))
22426 /* Issuing a load, swing the load_store_pendulum to the right */
22427 load_store_pendulum++;
22429 return cached_can_issue_more;
22431 /* If the pendulum is balanced, or there is only one instruction on
22432 the ready list, then all is well, so return. */
22433 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22434 return cached_can_issue_more;
22436 if (load_store_pendulum == 1)
22438 /* A load has been issued in this cycle. Scan the ready list
22439 for another load to issue with it */
22444 if (is_load_insn (ready[pos]))
22446 /* Found a load. Move it to the head of the ready list,
22447 and adjust it's priority so that it is more likely to
22450 for (i=pos; i<*pn_ready-1; i++)
22451 ready[i] = ready[i + 1];
22452 ready[*pn_ready-1] = tmp;
22454 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22455 INSN_PRIORITY (tmp)++;
22461 else if (load_store_pendulum == -2)
22463 /* Two stores have been issued in this cycle. Increase the
22464 priority of the first load in the ready list to favor it for
22465 issuing in the next cycle. */
22470 if (is_load_insn (ready[pos])
22472 && INSN_PRIORITY_KNOWN (ready[pos]))
22474 INSN_PRIORITY (ready[pos])++;
22476 /* Adjust the pendulum to account for the fact that a load
22477 was found and increased in priority. This is to prevent
22478 increasing the priority of multiple loads */
22479 load_store_pendulum--;
22486 else if (load_store_pendulum == -1)
22488 /* A store has been issued in this cycle. Scan the ready list for
22489 another store to issue with it, preferring a store to an adjacent
22491 int first_store_pos = -1;
22497 if (is_store_insn (ready[pos]))
22499 /* Maintain the index of the first store found on the
22501 if (first_store_pos == -1)
22502 first_store_pos = pos;
22504 if (is_store_insn (last_scheduled_insn)
22505 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22507 /* Found an adjacent store. Move it to the head of the
22508 ready list, and adjust it's priority so that it is
22509 more likely to stay there */
22511 for (i=pos; i<*pn_ready-1; i++)
22512 ready[i] = ready[i + 1];
22513 ready[*pn_ready-1] = tmp;
22515 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22516 INSN_PRIORITY (tmp)++;
22518 first_store_pos = -1;
22526 if (first_store_pos >= 0)
22528 /* An adjacent store wasn't found, but a non-adjacent store was,
22529 so move the non-adjacent store to the front of the ready
22530 list, and adjust its priority so that it is more likely to
22532 tmp = ready[first_store_pos];
22533 for (i=first_store_pos; i<*pn_ready-1; i++)
22534 ready[i] = ready[i + 1];
22535 ready[*pn_ready-1] = tmp;
22536 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22537 INSN_PRIORITY (tmp)++;
22540 else if (load_store_pendulum == 2)
22542 /* Two loads have been issued in this cycle. Increase the priority
22543 of the first store in the ready list to favor it for issuing in
22549 if (is_store_insn (ready[pos])
22551 && INSN_PRIORITY_KNOWN (ready[pos]))
22553 INSN_PRIORITY (ready[pos])++;
22555 /* Adjust the pendulum to account for the fact that a store
22556 was found and increased in priority. This is to prevent
22557 increasing the priority of multiple stores */
22558 load_store_pendulum++;
22567 return cached_can_issue_more;
22570 /* Return whether the presence of INSN causes a dispatch group termination
22571 of group WHICH_GROUP.
22573 If WHICH_GROUP == current_group, this function will return true if INSN
22574 causes the termination of the current group (i.e, the dispatch group to
22575 which INSN belongs). This means that INSN will be the last insn in the
22576 group it belongs to.
22578 If WHICH_GROUP == previous_group, this function will return true if INSN
22579 causes the termination of the previous group (i.e, the dispatch group that
22580 precedes the group to which INSN belongs). This means that INSN will be
22581 the first insn in the group it belongs to). */
22584 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22591 first = insn_must_be_first_in_group (insn);
22592 last = insn_must_be_last_in_group (insn);
22597 if (which_group == current_group)
22599 else if (which_group == previous_group)
22607 insn_must_be_first_in_group (rtx insn)
22609 enum attr_type type;
22612 || GET_CODE (insn) == NOTE
22613 || DEBUG_INSN_P (insn)
22614 || GET_CODE (PATTERN (insn)) == USE
22615 || GET_CODE (PATTERN (insn)) == CLOBBER)
22618 switch (rs6000_cpu)
22620 case PROCESSOR_POWER5:
22621 if (is_cracked_insn (insn))
22623 case PROCESSOR_POWER4:
22624 if (is_microcoded_insn (insn))
22627 if (!rs6000_sched_groups)
22630 type = get_attr_type (insn);
22637 case TYPE_DELAYED_CR:
22638 case TYPE_CR_LOGICAL:
22652 case PROCESSOR_POWER6:
22653 type = get_attr_type (insn);
22657 case TYPE_INSERT_DWORD:
22661 case TYPE_VAR_SHIFT_ROTATE:
22668 case TYPE_INSERT_WORD:
22669 case TYPE_DELAYED_COMPARE:
22670 case TYPE_IMUL_COMPARE:
22671 case TYPE_LMUL_COMPARE:
22672 case TYPE_FPCOMPARE:
22683 case TYPE_LOAD_EXT_UX:
22685 case TYPE_STORE_UX:
22686 case TYPE_FPLOAD_U:
22687 case TYPE_FPLOAD_UX:
22688 case TYPE_FPSTORE_U:
22689 case TYPE_FPSTORE_UX:
22695 case PROCESSOR_POWER7:
22696 type = get_attr_type (insn);
22700 case TYPE_CR_LOGICAL:
22707 case TYPE_DELAYED_COMPARE:
22708 case TYPE_VAR_DELAYED_COMPARE:
22714 case TYPE_LOAD_EXT:
22715 case TYPE_LOAD_EXT_U:
22716 case TYPE_LOAD_EXT_UX:
22718 case TYPE_STORE_UX:
22719 case TYPE_FPLOAD_U:
22720 case TYPE_FPLOAD_UX:
22721 case TYPE_FPSTORE_U:
22722 case TYPE_FPSTORE_UX:
22738 insn_must_be_last_in_group (rtx insn)
22740 enum attr_type type;
22743 || GET_CODE (insn) == NOTE
22744 || DEBUG_INSN_P (insn)
22745 || GET_CODE (PATTERN (insn)) == USE
22746 || GET_CODE (PATTERN (insn)) == CLOBBER)
22749 switch (rs6000_cpu) {
22750 case PROCESSOR_POWER4:
22751 case PROCESSOR_POWER5:
22752 if (is_microcoded_insn (insn))
22755 if (is_branch_slot_insn (insn))
22759 case PROCESSOR_POWER6:
22760 type = get_attr_type (insn);
22767 case TYPE_VAR_SHIFT_ROTATE:
22774 case TYPE_DELAYED_COMPARE:
22775 case TYPE_IMUL_COMPARE:
22776 case TYPE_LMUL_COMPARE:
22777 case TYPE_FPCOMPARE:
22791 case PROCESSOR_POWER7:
22792 type = get_attr_type (insn);
22800 case TYPE_LOAD_EXT_U:
22801 case TYPE_LOAD_EXT_UX:
22802 case TYPE_STORE_UX:
22815 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22816 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22819 is_costly_group (rtx *group_insns, rtx next_insn)
22822 int issue_rate = rs6000_issue_rate ();
22824 for (i = 0; i < issue_rate; i++)
22826 sd_iterator_def sd_it;
22828 rtx insn = group_insns[i];
22833 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22835 rtx next = DEP_CON (dep);
22837 if (next == next_insn
22838 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22846 /* Utility of the function redefine_groups.
22847 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22848 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22849 to keep it "far" (in a separate group) from GROUP_INSNS, following
22850 one of the following schemes, depending on the value of the flag
22851 -minsert_sched_nops = X:
22852 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22853 in order to force NEXT_INSN into a separate group.
22854 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22855 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22856 insertion (has a group just ended, how many vacant issue slots remain in the
22857 last group, and how many dispatch groups were encountered so far). */
22860 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22861 rtx next_insn, bool *group_end, int can_issue_more,
22866 int issue_rate = rs6000_issue_rate ();
22867 bool end = *group_end;
22870 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22871 return can_issue_more;
22873 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22874 return can_issue_more;
22876 force = is_costly_group (group_insns, next_insn);
22878 return can_issue_more;
22880 if (sched_verbose > 6)
22881 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22882 *group_count ,can_issue_more);
22884 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22887 can_issue_more = 0;
22889 /* Since only a branch can be issued in the last issue_slot, it is
22890 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22891 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22892 in this case the last nop will start a new group and the branch
22893 will be forced to the new group. */
22894 if (can_issue_more && !is_branch_slot_insn (next_insn))
22897 while (can_issue_more > 0)
22900 emit_insn_before (nop, next_insn);
22908 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22910 int n_nops = rs6000_sched_insert_nops;
22912 /* Nops can't be issued from the branch slot, so the effective
22913 issue_rate for nops is 'issue_rate - 1'. */
22914 if (can_issue_more == 0)
22915 can_issue_more = issue_rate;
22917 if (can_issue_more == 0)
22919 can_issue_more = issue_rate - 1;
22922 for (i = 0; i < issue_rate; i++)
22924 group_insns[i] = 0;
22931 emit_insn_before (nop, next_insn);
22932 if (can_issue_more == issue_rate - 1) /* new group begins */
22935 if (can_issue_more == 0)
22937 can_issue_more = issue_rate - 1;
22940 for (i = 0; i < issue_rate; i++)
22942 group_insns[i] = 0;
22948 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22951 /* Is next_insn going to start a new group? */
22954 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22955 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22956 || (can_issue_more < issue_rate &&
22957 insn_terminates_group_p (next_insn, previous_group)));
22958 if (*group_end && end)
22961 if (sched_verbose > 6)
22962 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22963 *group_count, can_issue_more);
22964 return can_issue_more;
22967 return can_issue_more;
22970 /* This function tries to synch the dispatch groups that the compiler "sees"
22971 with the dispatch groups that the processor dispatcher is expected to
22972 form in practice. It tries to achieve this synchronization by forcing the
22973 estimated processor grouping on the compiler (as opposed to the function
22974 'pad_goups' which tries to force the scheduler's grouping on the processor).
22976 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22977 examines the (estimated) dispatch groups that will be formed by the processor
22978 dispatcher. It marks these group boundaries to reflect the estimated
22979 processor grouping, overriding the grouping that the scheduler had marked.
22980 Depending on the value of the flag '-minsert-sched-nops' this function can
22981 force certain insns into separate groups or force a certain distance between
22982 them by inserting nops, for example, if there exists a "costly dependence"
22985 The function estimates the group boundaries that the processor will form as
22986 follows: It keeps track of how many vacant issue slots are available after
22987 each insn. A subsequent insn will start a new group if one of the following
22989 - no more vacant issue slots remain in the current dispatch group.
22990 - only the last issue slot, which is the branch slot, is vacant, but the next
22991 insn is not a branch.
22992 - only the last 2 or less issue slots, including the branch slot, are vacant,
22993 which means that a cracked insn (which occupies two issue slots) can't be
22994 issued in this group.
22995 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22996 start a new group. */
22999 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23001 rtx insn, next_insn;
23003 int can_issue_more;
23006 int group_count = 0;
23010 issue_rate = rs6000_issue_rate ();
23011 group_insns = XALLOCAVEC (rtx, issue_rate);
23012 for (i = 0; i < issue_rate; i++)
23014 group_insns[i] = 0;
23016 can_issue_more = issue_rate;
23018 insn = get_next_active_insn (prev_head_insn, tail);
23021 while (insn != NULL_RTX)
23023 slot = (issue_rate - can_issue_more);
23024 group_insns[slot] = insn;
23026 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23027 if (insn_terminates_group_p (insn, current_group))
23028 can_issue_more = 0;
23030 next_insn = get_next_active_insn (insn, tail);
23031 if (next_insn == NULL_RTX)
23032 return group_count + 1;
23034 /* Is next_insn going to start a new group? */
23036 = (can_issue_more == 0
23037 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23038 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23039 || (can_issue_more < issue_rate &&
23040 insn_terminates_group_p (next_insn, previous_group)));
23042 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23043 next_insn, &group_end, can_issue_more,
23049 can_issue_more = 0;
23050 for (i = 0; i < issue_rate; i++)
23052 group_insns[i] = 0;
23056 if (GET_MODE (next_insn) == TImode && can_issue_more)
23057 PUT_MODE (next_insn, VOIDmode);
23058 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23059 PUT_MODE (next_insn, TImode);
23062 if (can_issue_more == 0)
23063 can_issue_more = issue_rate;
23066 return group_count;
23069 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23070 dispatch group boundaries that the scheduler had marked. Pad with nops
23071 any dispatch groups which have vacant issue slots, in order to force the
23072 scheduler's grouping on the processor dispatcher. The function
23073 returns the number of dispatch groups found. */
23076 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23078 rtx insn, next_insn;
23081 int can_issue_more;
23083 int group_count = 0;
23085 /* Initialize issue_rate. */
23086 issue_rate = rs6000_issue_rate ();
23087 can_issue_more = issue_rate;
23089 insn = get_next_active_insn (prev_head_insn, tail);
23090 next_insn = get_next_active_insn (insn, tail);
23092 while (insn != NULL_RTX)
23095 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23097 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23099 if (next_insn == NULL_RTX)
23104 /* If the scheduler had marked group termination at this location
23105 (between insn and next_insn), and neither insn nor next_insn will
23106 force group termination, pad the group with nops to force group
23109 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23110 && !insn_terminates_group_p (insn, current_group)
23111 && !insn_terminates_group_p (next_insn, previous_group))
23113 if (!is_branch_slot_insn (next_insn))
23116 while (can_issue_more)
23119 emit_insn_before (nop, next_insn);
23124 can_issue_more = issue_rate;
23129 next_insn = get_next_active_insn (insn, tail);
23132 return group_count;
23135 /* We're beginning a new block. Initialize data structures as necessary. */
23138 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23139 int sched_verbose ATTRIBUTE_UNUSED,
23140 int max_ready ATTRIBUTE_UNUSED)
23142 last_scheduled_insn = NULL_RTX;
23143 load_store_pendulum = 0;
23146 /* The following function is called at the end of scheduling BB.
23147 After reload, it inserts nops at insn group bundling. */
23150 rs6000_sched_finish (FILE *dump, int sched_verbose)
23155 fprintf (dump, "=== Finishing schedule.\n");
23157 if (reload_completed && rs6000_sched_groups)
23159 /* Do not run sched_finish hook when selective scheduling enabled. */
23160 if (sel_sched_p ())
23163 if (rs6000_sched_insert_nops == sched_finish_none)
23166 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23167 n_groups = pad_groups (dump, sched_verbose,
23168 current_sched_info->prev_head,
23169 current_sched_info->next_tail);
23171 n_groups = redefine_groups (dump, sched_verbose,
23172 current_sched_info->prev_head,
23173 current_sched_info->next_tail);
23175 if (sched_verbose >= 6)
23177 fprintf (dump, "ngroups = %d\n", n_groups);
23178 print_rtl (dump, current_sched_info->prev_head);
23179 fprintf (dump, "Done finish_sched\n");
23184 struct _rs6000_sched_context
23186 short cached_can_issue_more;
23187 rtx last_scheduled_insn;
23188 int load_store_pendulum;
23191 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23192 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23194 /* Allocate store for new scheduling context. */
23196 rs6000_alloc_sched_context (void)
23198 return xmalloc (sizeof (rs6000_sched_context_def));
23201 /* If CLEAN_P is true then initializes _SC with clean data,
23202 and from the global context otherwise. */
23204 rs6000_init_sched_context (void *_sc, bool clean_p)
23206 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23210 sc->cached_can_issue_more = 0;
23211 sc->last_scheduled_insn = NULL_RTX;
23212 sc->load_store_pendulum = 0;
23216 sc->cached_can_issue_more = cached_can_issue_more;
23217 sc->last_scheduled_insn = last_scheduled_insn;
23218 sc->load_store_pendulum = load_store_pendulum;
23222 /* Sets the global scheduling context to the one pointed to by _SC. */
23224 rs6000_set_sched_context (void *_sc)
23226 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23228 gcc_assert (sc != NULL);
23230 cached_can_issue_more = sc->cached_can_issue_more;
23231 last_scheduled_insn = sc->last_scheduled_insn;
23232 load_store_pendulum = sc->load_store_pendulum;
23237 rs6000_free_sched_context (void *_sc)
23239 gcc_assert (_sc != NULL);
23245 /* Length in units of the trampoline for entering a nested function. */
23248 rs6000_trampoline_size (void)
23252 switch (DEFAULT_ABI)
23255 gcc_unreachable ();
23258 ret = (TARGET_32BIT) ? 12 : 24;
23263 ret = (TARGET_32BIT) ? 40 : 48;
23270 /* Emit RTL insns to initialize the variable parts of a trampoline.
23271 FNADDR is an RTX for the address of the function's pure code.
23272 CXT is an RTX for the static chain value for the function. */
23275 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23277 int regsize = (TARGET_32BIT) ? 4 : 8;
23278 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23279 rtx ctx_reg = force_reg (Pmode, cxt);
23280 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23282 switch (DEFAULT_ABI)
23285 gcc_unreachable ();
23287 /* Under AIX, just build the 3 word function descriptor */
23290 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23291 rtx fn_reg = gen_reg_rtx (Pmode);
23292 rtx toc_reg = gen_reg_rtx (Pmode);
23294 /* Macro to shorten the code expansions below. */
23295 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23297 m_tramp = replace_equiv_address (m_tramp, addr);
23299 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23300 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23301 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23302 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23303 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23309 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23312 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23313 LCT_NORMAL, VOIDmode, 4,
23315 GEN_INT (rs6000_trampoline_size ()), SImode,
23323 /* Handle the "altivec" attribute. The attribute may have
23324 arguments as follows:
23326 __attribute__((altivec(vector__)))
23327 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23328 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23330 and may appear more than once (e.g., 'vector bool char') in a
23331 given declaration. */
23334 rs6000_handle_altivec_attribute (tree *node,
23335 tree name ATTRIBUTE_UNUSED,
23337 int flags ATTRIBUTE_UNUSED,
23338 bool *no_add_attrs)
23340 tree type = *node, result = NULL_TREE;
23341 enum machine_mode mode;
23344 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23345 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23346 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23349 while (POINTER_TYPE_P (type)
23350 || TREE_CODE (type) == FUNCTION_TYPE
23351 || TREE_CODE (type) == METHOD_TYPE
23352 || TREE_CODE (type) == ARRAY_TYPE)
23353 type = TREE_TYPE (type);
23355 mode = TYPE_MODE (type);
23357 /* Check for invalid AltiVec type qualifiers. */
23358 if (type == long_double_type_node)
23359 error ("use of %<long double%> in AltiVec types is invalid");
23360 else if (type == boolean_type_node)
23361 error ("use of boolean types in AltiVec types is invalid");
23362 else if (TREE_CODE (type) == COMPLEX_TYPE)
23363 error ("use of %<complex%> in AltiVec types is invalid");
23364 else if (DECIMAL_FLOAT_MODE_P (mode))
23365 error ("use of decimal floating point types in AltiVec types is invalid");
23366 else if (!TARGET_VSX)
23368 if (type == long_unsigned_type_node || type == long_integer_type_node)
23371 error ("use of %<long%> in AltiVec types is invalid for "
23372 "64-bit code without -mvsx");
23373 else if (rs6000_warn_altivec_long)
23374 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23377 else if (type == long_long_unsigned_type_node
23378 || type == long_long_integer_type_node)
23379 error ("use of %<long long%> in AltiVec types is invalid without "
23381 else if (type == double_type_node)
23382 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23385 switch (altivec_type)
23388 unsigned_p = TYPE_UNSIGNED (type);
23392 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23395 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23398 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23401 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23403 case SFmode: result = V4SF_type_node; break;
23404 case DFmode: result = V2DF_type_node; break;
23405 /* If the user says 'vector int bool', we may be handed the 'bool'
23406 attribute _before_ the 'vector' attribute, and so select the
23407 proper type in the 'b' case below. */
23408 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23409 case V2DImode: case V2DFmode:
23417 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23418 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23419 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23420 case QImode: case V16QImode: result = bool_V16QI_type_node;
23427 case V8HImode: result = pixel_V8HI_type_node;
23433 /* Propagate qualifiers attached to the element type
23434 onto the vector type. */
23435 if (result && result != type && TYPE_QUALS (type))
23436 result = build_qualified_type (result, TYPE_QUALS (type));
23438 *no_add_attrs = true; /* No need to hang on to the attribute. */
23441 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23446 /* AltiVec defines four built-in scalar types that serve as vector
23447 elements; we must teach the compiler how to mangle them. */
23449 static const char *
23450 rs6000_mangle_type (const_tree type)
23452 type = TYPE_MAIN_VARIANT (type);
23454 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23455 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23458 if (type == bool_char_type_node) return "U6__boolc";
23459 if (type == bool_short_type_node) return "U6__bools";
23460 if (type == pixel_type_node) return "u7__pixel";
23461 if (type == bool_int_type_node) return "U6__booli";
23462 if (type == bool_long_type_node) return "U6__booll";
23464 /* Mangle IBM extended float long double as `g' (__float128) on
23465 powerpc*-linux where long-double-64 previously was the default. */
23466 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23468 && TARGET_LONG_DOUBLE_128
23469 && !TARGET_IEEEQUAD)
23472 /* For all other types, use normal C++ mangling. */
23476 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23477 struct attribute_spec.handler. */
23480 rs6000_handle_longcall_attribute (tree *node, tree name,
23481 tree args ATTRIBUTE_UNUSED,
23482 int flags ATTRIBUTE_UNUSED,
23483 bool *no_add_attrs)
23485 if (TREE_CODE (*node) != FUNCTION_TYPE
23486 && TREE_CODE (*node) != FIELD_DECL
23487 && TREE_CODE (*node) != TYPE_DECL)
23489 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23491 *no_add_attrs = true;
23497 /* Set longcall attributes on all functions declared when
23498 rs6000_default_long_calls is true. */
23500 rs6000_set_default_type_attributes (tree type)
23502 if (rs6000_default_long_calls
23503 && (TREE_CODE (type) == FUNCTION_TYPE
23504 || TREE_CODE (type) == METHOD_TYPE))
23505 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23507 TYPE_ATTRIBUTES (type));
23510 darwin_set_default_type_attributes (type);
23514 /* Return a reference suitable for calling a function with the
23515 longcall attribute. */
23518 rs6000_longcall_ref (rtx call_ref)
23520 const char *call_name;
23523 if (GET_CODE (call_ref) != SYMBOL_REF)
23526 /* System V adds '.' to the internal name, so skip them. */
23527 call_name = XSTR (call_ref, 0);
23528 if (*call_name == '.')
23530 while (*call_name == '.')
23533 node = get_identifier (call_name);
23534 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23537 return force_reg (Pmode, call_ref);
23540 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23541 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23544 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23545 struct attribute_spec.handler. */
23547 rs6000_handle_struct_attribute (tree *node, tree name,
23548 tree args ATTRIBUTE_UNUSED,
23549 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23552 if (DECL_P (*node))
23554 if (TREE_CODE (*node) == TYPE_DECL)
23555 type = &TREE_TYPE (*node);
23560 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23561 || TREE_CODE (*type) == UNION_TYPE)))
23563 warning (OPT_Wattributes, "%qE attribute ignored", name);
23564 *no_add_attrs = true;
23567 else if ((is_attribute_p ("ms_struct", name)
23568 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23569 || ((is_attribute_p ("gcc_struct", name)
23570 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23572 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23574 *no_add_attrs = true;
23581 rs6000_ms_bitfield_layout_p (const_tree record_type)
23583 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23584 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23585 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23588 #ifdef USING_ELFOS_H
23590 /* A get_unnamed_section callback, used for switching to toc_section. */
23593 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23595 if (DEFAULT_ABI == ABI_AIX
23596 && TARGET_MINIMAL_TOC
23597 && !TARGET_RELOCATABLE)
23599 if (!toc_initialized)
23601 toc_initialized = 1;
23602 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23603 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23604 fprintf (asm_out_file, "\t.tc ");
23605 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23606 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23607 fprintf (asm_out_file, "\n");
23609 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23610 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23611 fprintf (asm_out_file, " = .+32768\n");
23614 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23616 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23617 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23620 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23621 if (!toc_initialized)
23623 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23624 fprintf (asm_out_file, " = .+32768\n");
23625 toc_initialized = 1;
23630 /* Implement TARGET_ASM_INIT_SECTIONS. */
23633 rs6000_elf_asm_init_sections (void)
23636 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23639 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23640 SDATA2_SECTION_ASM_OP);
23643 /* Implement TARGET_SELECT_RTX_SECTION. */
23646 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23647 unsigned HOST_WIDE_INT align)
23649 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23650 return toc_section;
23652 return default_elf_select_rtx_section (mode, x, align);
23655 /* For a SYMBOL_REF, set generic flags and then perform some
23656 target-specific processing.
23658 When the AIX ABI is requested on a non-AIX system, replace the
23659 function name with the real name (with a leading .) rather than the
23660 function descriptor name. This saves a lot of overriding code to
23661 read the prefixes. */
23664 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23666 default_encode_section_info (decl, rtl, first);
23669 && TREE_CODE (decl) == FUNCTION_DECL
23671 && DEFAULT_ABI == ABI_AIX)
23673 rtx sym_ref = XEXP (rtl, 0);
23674 size_t len = strlen (XSTR (sym_ref, 0));
23675 char *str = XALLOCAVEC (char, len + 2);
23677 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23678 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23683 compare_section_name (const char *section, const char *templ)
23687 len = strlen (templ);
23688 return (strncmp (section, templ, len) == 0
23689 && (section[len] == 0 || section[len] == '.'));
23693 rs6000_elf_in_small_data_p (const_tree decl)
23695 if (rs6000_sdata == SDATA_NONE)
23698 /* We want to merge strings, so we never consider them small data. */
23699 if (TREE_CODE (decl) == STRING_CST)
23702 /* Functions are never in the small data area. */
23703 if (TREE_CODE (decl) == FUNCTION_DECL)
23706 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23708 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23709 if (compare_section_name (section, ".sdata")
23710 || compare_section_name (section, ".sdata2")
23711 || compare_section_name (section, ".gnu.linkonce.s")
23712 || compare_section_name (section, ".sbss")
23713 || compare_section_name (section, ".sbss2")
23714 || compare_section_name (section, ".gnu.linkonce.sb")
23715 || strcmp (section, ".PPC.EMB.sdata0") == 0
23716 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23721 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23724 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23725 /* If it's not public, and we're not going to reference it there,
23726 there's no need to put it in the small data section. */
23727 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23734 #endif /* USING_ELFOS_H */
23736 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23739 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23741 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23744 /* Return a REG that occurs in ADDR with coefficient 1.
23745 ADDR can be effectively incremented by incrementing REG.
23747 r0 is special and we must not select it as an address
23748 register by this routine since our caller will try to
23749 increment the returned register via an "la" instruction. */
23752 find_addr_reg (rtx addr)
23754 while (GET_CODE (addr) == PLUS)
23756 if (GET_CODE (XEXP (addr, 0)) == REG
23757 && REGNO (XEXP (addr, 0)) != 0)
23758 addr = XEXP (addr, 0);
23759 else if (GET_CODE (XEXP (addr, 1)) == REG
23760 && REGNO (XEXP (addr, 1)) != 0)
23761 addr = XEXP (addr, 1);
23762 else if (CONSTANT_P (XEXP (addr, 0)))
23763 addr = XEXP (addr, 1);
23764 else if (CONSTANT_P (XEXP (addr, 1)))
23765 addr = XEXP (addr, 0);
23767 gcc_unreachable ();
23769 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23774 rs6000_fatal_bad_address (rtx op)
23776 fatal_insn ("bad address", op);
23781 static tree branch_island_list = 0;
23783 /* Remember to generate a branch island for far calls to the given
23787 add_compiler_branch_island (tree label_name, tree function_name,
23790 tree branch_island = build_tree_list (function_name, label_name);
23791 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23792 TREE_CHAIN (branch_island) = branch_island_list;
23793 branch_island_list = branch_island;
23796 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23797 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23798 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23799 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23801 /* Generate far-jump branch islands for everything on the
23802 branch_island_list. Invoked immediately after the last instruction
23803 of the epilogue has been emitted; the branch-islands must be
23804 appended to, and contiguous with, the function body. Mach-O stubs
23805 are generated in machopic_output_stub(). */
23808 macho_branch_islands (void)
23811 tree branch_island;
23813 for (branch_island = branch_island_list;
23815 branch_island = TREE_CHAIN (branch_island))
23817 const char *label =
23818 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23820 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23821 char name_buf[512];
23822 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23823 if (name[0] == '*' || name[0] == '&')
23824 strcpy (name_buf, name+1);
23828 strcpy (name_buf+1, name);
23830 strcpy (tmp_buf, "\n");
23831 strcat (tmp_buf, label);
23832 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23833 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23834 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23835 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23838 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23839 strcat (tmp_buf, label);
23840 strcat (tmp_buf, "_pic\n");
23841 strcat (tmp_buf, label);
23842 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23844 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23845 strcat (tmp_buf, name_buf);
23846 strcat (tmp_buf, " - ");
23847 strcat (tmp_buf, label);
23848 strcat (tmp_buf, "_pic)\n");
23850 strcat (tmp_buf, "\tmtlr r0\n");
23852 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23853 strcat (tmp_buf, name_buf);
23854 strcat (tmp_buf, " - ");
23855 strcat (tmp_buf, label);
23856 strcat (tmp_buf, "_pic)\n");
23858 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23862 strcat (tmp_buf, ":\nlis r12,hi16(");
23863 strcat (tmp_buf, name_buf);
23864 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23865 strcat (tmp_buf, name_buf);
23866 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23868 output_asm_insn (tmp_buf, 0);
23869 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23870 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23871 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23872 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23875 branch_island_list = 0;
23878 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23879 already there or not. */
23882 no_previous_def (tree function_name)
23884 tree branch_island;
23885 for (branch_island = branch_island_list;
23887 branch_island = TREE_CHAIN (branch_island))
23888 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23893 /* GET_PREV_LABEL gets the label name from the previous definition of
23897 get_prev_label (tree function_name)
23899 tree branch_island;
23900 for (branch_island = branch_island_list;
23902 branch_island = TREE_CHAIN (branch_island))
23903 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23904 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23908 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23909 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23912 /* KEXTs still need branch islands. */
23913 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23914 || flag_mkernel || flag_apple_kext)
23916 /* INSN is either a function call or a millicode call. It may have an
23917 unconditional jump in its delay slot.
23919 CALL_DEST is the routine we are calling. */
23922 output_call (rtx insn, rtx *operands, int dest_operand_number,
23923 int cookie_operand_number)
23925 static char buf[256];
23926 if (DARWIN_GENERATE_ISLANDS
23927 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23928 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23931 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23933 if (no_previous_def (funname))
23935 rtx label_rtx = gen_label_rtx ();
23936 char *label_buf, temp_buf[256];
23937 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23938 CODE_LABEL_NUMBER (label_rtx));
23939 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23940 labelname = get_identifier (label_buf);
23941 add_compiler_branch_island (labelname, funname, insn_line (insn));
23944 labelname = get_prev_label (funname);
23946 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23947 instruction will reach 'foo', otherwise link as 'bl L42'".
23948 "L42" should be a 'branch island', that will do a far jump to
23949 'foo'. Branch islands are generated in
23950 macho_branch_islands(). */
23951 sprintf (buf, "jbsr %%z%d,%.246s",
23952 dest_operand_number, IDENTIFIER_POINTER (labelname));
23955 sprintf (buf, "bl %%z%d", dest_operand_number);
23959 /* Generate PIC and indirect symbol stubs. */
23962 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23964 unsigned int length;
23965 char *symbol_name, *lazy_ptr_name;
23966 char *local_label_0;
23967 static int label = 0;
23969 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23970 symb = (*targetm.strip_name_encoding) (symb);
23973 length = strlen (symb);
23974 symbol_name = XALLOCAVEC (char, length + 32);
23975 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23977 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23978 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23981 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23983 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23987 fprintf (file, "\t.align 5\n");
23989 fprintf (file, "%s:\n", stub);
23990 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23993 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23994 sprintf (local_label_0, "\"L%011d$spb\"", label);
23996 fprintf (file, "\tmflr r0\n");
23997 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23998 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23999 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24000 lazy_ptr_name, local_label_0);
24001 fprintf (file, "\tmtlr r0\n");
24002 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24003 (TARGET_64BIT ? "ldu" : "lwzu"),
24004 lazy_ptr_name, local_label_0);
24005 fprintf (file, "\tmtctr r12\n");
24006 fprintf (file, "\tbctr\n");
24010 fprintf (file, "\t.align 4\n");
24012 fprintf (file, "%s:\n", stub);
24013 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24015 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24016 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24017 (TARGET_64BIT ? "ldu" : "lwzu"),
24019 fprintf (file, "\tmtctr r12\n");
24020 fprintf (file, "\tbctr\n");
24023 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24024 fprintf (file, "%s:\n", lazy_ptr_name);
24025 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24026 fprintf (file, "%sdyld_stub_binding_helper\n",
24027 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24030 /* Legitimize PIC addresses. If the address is already
24031 position-independent, we return ORIG. Newly generated
24032 position-independent addresses go into a reg. This is REG if non
24033 zero, otherwise we allocate register(s) as necessary. */
24035 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24038 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24043 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24044 reg = gen_reg_rtx (Pmode);
24046 if (GET_CODE (orig) == CONST)
24050 if (GET_CODE (XEXP (orig, 0)) == PLUS
24051 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24054 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24056 /* Use a different reg for the intermediate value, as
24057 it will be marked UNCHANGING. */
24058 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24059 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24062 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24065 if (GET_CODE (offset) == CONST_INT)
24067 if (SMALL_INT (offset))
24068 return plus_constant (base, INTVAL (offset));
24069 else if (! reload_in_progress && ! reload_completed)
24070 offset = force_reg (Pmode, offset);
24073 rtx mem = force_const_mem (Pmode, orig);
24074 return machopic_legitimize_pic_address (mem, Pmode, reg);
24077 return gen_rtx_PLUS (Pmode, base, offset);
24080 /* Fall back on generic machopic code. */
24081 return machopic_legitimize_pic_address (orig, mode, reg);
24084 /* Output a .machine directive for the Darwin assembler, and call
24085 the generic start_file routine. */
24088 rs6000_darwin_file_start (void)
24090 static const struct
24096 { "ppc64", "ppc64", MASK_64BIT },
24097 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24098 { "power4", "ppc970", 0 },
24099 { "G5", "ppc970", 0 },
24100 { "7450", "ppc7450", 0 },
24101 { "7400", "ppc7400", MASK_ALTIVEC },
24102 { "G4", "ppc7400", 0 },
24103 { "750", "ppc750", 0 },
24104 { "740", "ppc750", 0 },
24105 { "G3", "ppc750", 0 },
24106 { "604e", "ppc604e", 0 },
24107 { "604", "ppc604", 0 },
24108 { "603e", "ppc603", 0 },
24109 { "603", "ppc603", 0 },
24110 { "601", "ppc601", 0 },
24111 { NULL, "ppc", 0 } };
24112 const char *cpu_id = "";
24115 rs6000_file_start ();
24116 darwin_file_start ();
24118 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24119 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24120 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24121 && rs6000_select[i].string[0] != '\0')
24122 cpu_id = rs6000_select[i].string;
24124 /* Look through the mapping array. Pick the first name that either
24125 matches the argument, has a bit set in IF_SET that is also set
24126 in the target flags, or has a NULL name. */
24129 while (mapping[i].arg != NULL
24130 && strcmp (mapping[i].arg, cpu_id) != 0
24131 && (mapping[i].if_set & target_flags) == 0)
24134 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24137 #endif /* TARGET_MACHO */
24141 rs6000_elf_reloc_rw_mask (void)
24145 else if (DEFAULT_ABI == ABI_AIX)
24151 /* Record an element in the table of global constructors. SYMBOL is
24152 a SYMBOL_REF of the function to be called; PRIORITY is a number
24153 between 0 and MAX_INIT_PRIORITY.
24155 This differs from default_named_section_asm_out_constructor in
24156 that we have special handling for -mrelocatable. */
24159 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24161 const char *section = ".ctors";
24164 if (priority != DEFAULT_INIT_PRIORITY)
24166 sprintf (buf, ".ctors.%.5u",
24167 /* Invert the numbering so the linker puts us in the proper
24168 order; constructors are run from right to left, and the
24169 linker sorts in increasing order. */
24170 MAX_INIT_PRIORITY - priority);
24174 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24175 assemble_align (POINTER_SIZE);
24177 if (TARGET_RELOCATABLE)
24179 fputs ("\t.long (", asm_out_file);
24180 output_addr_const (asm_out_file, symbol);
24181 fputs (")@fixup\n", asm_out_file);
24184 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24188 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24190 const char *section = ".dtors";
24193 if (priority != DEFAULT_INIT_PRIORITY)
24195 sprintf (buf, ".dtors.%.5u",
24196 /* Invert the numbering so the linker puts us in the proper
24197 order; constructors are run from right to left, and the
24198 linker sorts in increasing order. */
24199 MAX_INIT_PRIORITY - priority);
24203 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24204 assemble_align (POINTER_SIZE);
24206 if (TARGET_RELOCATABLE)
24208 fputs ("\t.long (", asm_out_file);
24209 output_addr_const (asm_out_file, symbol);
24210 fputs (")@fixup\n", asm_out_file);
24213 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24217 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24221 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24222 ASM_OUTPUT_LABEL (file, name);
24223 fputs (DOUBLE_INT_ASM_OP, file);
24224 rs6000_output_function_entry (file, name);
24225 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24228 fputs ("\t.size\t", file);
24229 assemble_name (file, name);
24230 fputs (",24\n\t.type\t.", file);
24231 assemble_name (file, name);
24232 fputs (",@function\n", file);
24233 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24235 fputs ("\t.globl\t.", file);
24236 assemble_name (file, name);
24241 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24242 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24243 rs6000_output_function_entry (file, name);
24244 fputs (":\n", file);
24248 if (TARGET_RELOCATABLE
24249 && !TARGET_SECURE_PLT
24250 && (get_pool_size () != 0 || crtl->profile)
24255 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24257 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24258 fprintf (file, "\t.long ");
24259 assemble_name (file, buf);
24261 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24262 assemble_name (file, buf);
24266 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24267 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24269 if (DEFAULT_ABI == ABI_AIX)
24271 const char *desc_name, *orig_name;
24273 orig_name = (*targetm.strip_name_encoding) (name);
24274 desc_name = orig_name;
24275 while (*desc_name == '.')
24278 if (TREE_PUBLIC (decl))
24279 fprintf (file, "\t.globl %s\n", desc_name);
24281 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24282 fprintf (file, "%s:\n", desc_name);
24283 fprintf (file, "\t.long %s\n", orig_name);
24284 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24285 if (DEFAULT_ABI == ABI_AIX)
24286 fputs ("\t.long 0\n", file);
24287 fprintf (file, "\t.previous\n");
24289 ASM_OUTPUT_LABEL (file, name);
24293 rs6000_elf_end_indicate_exec_stack (void)
24296 file_end_indicate_exec_stack ();
24302 rs6000_xcoff_asm_output_anchor (rtx symbol)
24306 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24307 SYMBOL_REF_BLOCK_OFFSET (symbol));
24308 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24312 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24314 fputs (GLOBAL_ASM_OP, stream);
24315 RS6000_OUTPUT_BASENAME (stream, name);
24316 putc ('\n', stream);
24319 /* A get_unnamed_decl callback, used for read-only sections. PTR
24320 points to the section string variable. */
24323 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24325 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24326 *(const char *const *) directive,
24327 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24330 /* Likewise for read-write sections. */
24333 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24335 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24336 *(const char *const *) directive,
24337 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24340 /* A get_unnamed_section callback, used for switching to toc_section. */
24343 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24345 if (TARGET_MINIMAL_TOC)
24347 /* toc_section is always selected at least once from
24348 rs6000_xcoff_file_start, so this is guaranteed to
24349 always be defined once and only once in each file. */
24350 if (!toc_initialized)
24352 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24353 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24354 toc_initialized = 1;
24356 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24357 (TARGET_32BIT ? "" : ",3"));
24360 fputs ("\t.toc\n", asm_out_file);
24363 /* Implement TARGET_ASM_INIT_SECTIONS. */
24366 rs6000_xcoff_asm_init_sections (void)
24368 read_only_data_section
24369 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24370 &xcoff_read_only_section_name);
24372 private_data_section
24373 = get_unnamed_section (SECTION_WRITE,
24374 rs6000_xcoff_output_readwrite_section_asm_op,
24375 &xcoff_private_data_section_name);
24377 read_only_private_data_section
24378 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24379 &xcoff_private_data_section_name);
24382 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24384 readonly_data_section = read_only_data_section;
24385 exception_section = data_section;
24389 rs6000_xcoff_reloc_rw_mask (void)
24395 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24396 tree decl ATTRIBUTE_UNUSED)
24399 static const char * const suffix[3] = { "PR", "RO", "RW" };
24401 if (flags & SECTION_CODE)
24403 else if (flags & SECTION_WRITE)
24408 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24409 (flags & SECTION_CODE) ? "." : "",
24410 name, suffix[smclass], flags & SECTION_ENTSIZE);
24414 rs6000_xcoff_select_section (tree decl, int reloc,
24415 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24417 if (decl_readonly_section (decl, reloc))
24419 if (TREE_PUBLIC (decl))
24420 return read_only_data_section;
24422 return read_only_private_data_section;
24426 if (TREE_PUBLIC (decl))
24427 return data_section;
24429 return private_data_section;
24434 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24438 /* Use select_section for private and uninitialized data. */
24439 if (!TREE_PUBLIC (decl)
24440 || DECL_COMMON (decl)
24441 || DECL_INITIAL (decl) == NULL_TREE
24442 || DECL_INITIAL (decl) == error_mark_node
24443 || (flag_zero_initialized_in_bss
24444 && initializer_zerop (DECL_INITIAL (decl))))
24447 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24448 name = (*targetm.strip_name_encoding) (name);
24449 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24452 /* Select section for constant in constant pool.
24454 On RS/6000, all constants are in the private read-only data area.
24455 However, if this is being placed in the TOC it must be output as a
24459 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24460 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24462 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24463 return toc_section;
24465 return read_only_private_data_section;
24468 /* Remove any trailing [DS] or the like from the symbol name. */
24470 static const char *
24471 rs6000_xcoff_strip_name_encoding (const char *name)
24476 len = strlen (name);
24477 if (name[len - 1] == ']')
24478 return ggc_alloc_string (name, len - 4);
24483 /* Section attributes. AIX is always PIC. */
24485 static unsigned int
24486 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24488 unsigned int align;
24489 unsigned int flags = default_section_type_flags (decl, name, reloc);
24491 /* Align to at least UNIT size. */
24492 if (flags & SECTION_CODE)
24493 align = MIN_UNITS_PER_WORD;
24495 /* Increase alignment of large objects if not already stricter. */
24496 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24497 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24498 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24500 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24503 /* Output at beginning of assembler file.
24505 Initialize the section names for the RS/6000 at this point.
24507 Specify filename, including full path, to assembler.
24509 We want to go into the TOC section so at least one .toc will be emitted.
24510 Also, in order to output proper .bs/.es pairs, we need at least one static
24511 [RW] section emitted.
24513 Finally, declare mcount when profiling to make the assembler happy. */
24516 rs6000_xcoff_file_start (void)
24518 rs6000_gen_section_name (&xcoff_bss_section_name,
24519 main_input_filename, ".bss_");
24520 rs6000_gen_section_name (&xcoff_private_data_section_name,
24521 main_input_filename, ".rw_");
24522 rs6000_gen_section_name (&xcoff_read_only_section_name,
24523 main_input_filename, ".ro_");
24525 fputs ("\t.file\t", asm_out_file);
24526 output_quoted_string (asm_out_file, main_input_filename);
24527 fputc ('\n', asm_out_file);
24528 if (write_symbols != NO_DEBUG)
24529 switch_to_section (private_data_section);
24530 switch_to_section (text_section);
24532 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24533 rs6000_file_start ();
24536 /* Output at end of assembler file.
24537 On the RS/6000, referencing data should automatically pull in text. */
24540 rs6000_xcoff_file_end (void)
24542 switch_to_section (text_section);
24543 fputs ("_section_.text:\n", asm_out_file);
24544 switch_to_section (data_section);
24545 fputs (TARGET_32BIT
24546 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24549 #endif /* TARGET_XCOFF */
24551 /* Compute a (partial) cost for rtx X. Return true if the complete
24552 cost has been computed, and false if subexpressions should be
24553 scanned. In either case, *TOTAL contains the cost result. */
24556 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24559 enum machine_mode mode = GET_MODE (x);
24563 /* On the RS/6000, if it is valid in the insn, it is free. */
24565 if (((outer_code == SET
24566 || outer_code == PLUS
24567 || outer_code == MINUS)
24568 && (satisfies_constraint_I (x)
24569 || satisfies_constraint_L (x)))
24570 || (outer_code == AND
24571 && (satisfies_constraint_K (x)
24573 ? satisfies_constraint_L (x)
24574 : satisfies_constraint_J (x))
24575 || mask_operand (x, mode)
24577 && mask64_operand (x, DImode))))
24578 || ((outer_code == IOR || outer_code == XOR)
24579 && (satisfies_constraint_K (x)
24581 ? satisfies_constraint_L (x)
24582 : satisfies_constraint_J (x))))
24583 || outer_code == ASHIFT
24584 || outer_code == ASHIFTRT
24585 || outer_code == LSHIFTRT
24586 || outer_code == ROTATE
24587 || outer_code == ROTATERT
24588 || outer_code == ZERO_EXTRACT
24589 || (outer_code == MULT
24590 && satisfies_constraint_I (x))
24591 || ((outer_code == DIV || outer_code == UDIV
24592 || outer_code == MOD || outer_code == UMOD)
24593 && exact_log2 (INTVAL (x)) >= 0)
24594 || (outer_code == COMPARE
24595 && (satisfies_constraint_I (x)
24596 || satisfies_constraint_K (x)))
24597 || (outer_code == EQ
24598 && (satisfies_constraint_I (x)
24599 || satisfies_constraint_K (x)
24601 ? satisfies_constraint_L (x)
24602 : satisfies_constraint_J (x))))
24603 || (outer_code == GTU
24604 && satisfies_constraint_I (x))
24605 || (outer_code == LTU
24606 && satisfies_constraint_P (x)))
24611 else if ((outer_code == PLUS
24612 && reg_or_add_cint_operand (x, VOIDmode))
24613 || (outer_code == MINUS
24614 && reg_or_sub_cint_operand (x, VOIDmode))
24615 || ((outer_code == SET
24616 || outer_code == IOR
24617 || outer_code == XOR)
24619 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24621 *total = COSTS_N_INSNS (1);
24627 if (mode == DImode && code == CONST_DOUBLE)
24629 if ((outer_code == IOR || outer_code == XOR)
24630 && CONST_DOUBLE_HIGH (x) == 0
24631 && (CONST_DOUBLE_LOW (x)
24632 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24637 else if ((outer_code == AND && and64_2_operand (x, DImode))
24638 || ((outer_code == SET
24639 || outer_code == IOR
24640 || outer_code == XOR)
24641 && CONST_DOUBLE_HIGH (x) == 0))
24643 *total = COSTS_N_INSNS (1);
24653 /* When optimizing for size, MEM should be slightly more expensive
24654 than generating address, e.g., (plus (reg) (const)).
24655 L1 cache latency is about two instructions. */
24656 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24664 if (mode == DFmode)
24666 if (GET_CODE (XEXP (x, 0)) == MULT)
24668 /* FNMA accounted in outer NEG. */
24669 if (outer_code == NEG)
24670 *total = rs6000_cost->dmul - rs6000_cost->fp;
24672 *total = rs6000_cost->dmul;
24675 *total = rs6000_cost->fp;
24677 else if (mode == SFmode)
24679 /* FNMA accounted in outer NEG. */
24680 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24683 *total = rs6000_cost->fp;
24686 *total = COSTS_N_INSNS (1);
24690 if (mode == DFmode)
24692 if (GET_CODE (XEXP (x, 0)) == MULT
24693 || GET_CODE (XEXP (x, 1)) == MULT)
24695 /* FNMA accounted in outer NEG. */
24696 if (outer_code == NEG)
24697 *total = rs6000_cost->dmul - rs6000_cost->fp;
24699 *total = rs6000_cost->dmul;
24702 *total = rs6000_cost->fp;
24704 else if (mode == SFmode)
24706 /* FNMA accounted in outer NEG. */
24707 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24710 *total = rs6000_cost->fp;
24713 *total = COSTS_N_INSNS (1);
24717 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24718 && satisfies_constraint_I (XEXP (x, 1)))
24720 if (INTVAL (XEXP (x, 1)) >= -256
24721 && INTVAL (XEXP (x, 1)) <= 255)
24722 *total = rs6000_cost->mulsi_const9;
24724 *total = rs6000_cost->mulsi_const;
24726 /* FMA accounted in outer PLUS/MINUS. */
24727 else if ((mode == DFmode || mode == SFmode)
24728 && (outer_code == PLUS || outer_code == MINUS))
24730 else if (mode == DFmode)
24731 *total = rs6000_cost->dmul;
24732 else if (mode == SFmode)
24733 *total = rs6000_cost->fp;
24734 else if (mode == DImode)
24735 *total = rs6000_cost->muldi;
24737 *total = rs6000_cost->mulsi;
24742 if (FLOAT_MODE_P (mode))
24744 *total = mode == DFmode ? rs6000_cost->ddiv
24745 : rs6000_cost->sdiv;
24752 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24753 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24755 if (code == DIV || code == MOD)
24757 *total = COSTS_N_INSNS (2);
24760 *total = COSTS_N_INSNS (1);
24764 if (GET_MODE (XEXP (x, 1)) == DImode)
24765 *total = rs6000_cost->divdi;
24767 *total = rs6000_cost->divsi;
24769 /* Add in shift and subtract for MOD. */
24770 if (code == MOD || code == UMOD)
24771 *total += COSTS_N_INSNS (2);
24776 *total = COSTS_N_INSNS (4);
24780 *total = COSTS_N_INSNS (6);
24784 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24796 *total = COSTS_N_INSNS (1);
24804 /* Handle mul_highpart. */
24805 if (outer_code == TRUNCATE
24806 && GET_CODE (XEXP (x, 0)) == MULT)
24808 if (mode == DImode)
24809 *total = rs6000_cost->muldi;
24811 *total = rs6000_cost->mulsi;
24814 else if (outer_code == AND)
24817 *total = COSTS_N_INSNS (1);
24822 if (GET_CODE (XEXP (x, 0)) == MEM)
24825 *total = COSTS_N_INSNS (1);
24831 if (!FLOAT_MODE_P (mode))
24833 *total = COSTS_N_INSNS (1);
24839 case UNSIGNED_FLOAT:
24842 case FLOAT_TRUNCATE:
24843 *total = rs6000_cost->fp;
24847 if (mode == DFmode)
24850 *total = rs6000_cost->fp;
24854 switch (XINT (x, 1))
24857 *total = rs6000_cost->fp;
24869 *total = COSTS_N_INSNS (1);
24872 else if (FLOAT_MODE_P (mode)
24873 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24875 *total = rs6000_cost->fp;
24883 /* Carry bit requires mode == Pmode.
24884 NEG or PLUS already counted so only add one. */
24886 && (outer_code == NEG || outer_code == PLUS))
24888 *total = COSTS_N_INSNS (1);
24891 if (outer_code == SET)
24893 if (XEXP (x, 1) == const0_rtx)
24895 if (TARGET_ISEL && !TARGET_MFCRF)
24896 *total = COSTS_N_INSNS (8);
24898 *total = COSTS_N_INSNS (2);
24901 else if (mode == Pmode)
24903 *total = COSTS_N_INSNS (3);
24912 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24914 if (TARGET_ISEL && !TARGET_MFCRF)
24915 *total = COSTS_N_INSNS (8);
24917 *total = COSTS_N_INSNS (2);
24921 if (outer_code == COMPARE)
24935 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24938 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24941 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24944 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24945 "total = %d, speed = %s, x:\n",
24946 ret ? "complete" : "scan inner",
24947 GET_RTX_NAME (code),
24948 GET_RTX_NAME (outer_code),
24950 speed ? "true" : "false");
24957 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24960 rs6000_debug_address_cost (rtx x, bool speed)
24962 int ret = TARGET_ADDRESS_COST (x, speed);
24964 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24965 ret, speed ? "true" : "false");
24972 /* A C expression returning the cost of moving data from a register of class
24973 CLASS1 to one of CLASS2. */
24976 rs6000_register_move_cost (enum machine_mode mode,
24977 enum reg_class from, enum reg_class to)
24981 /* Moves from/to GENERAL_REGS. */
24982 if (reg_classes_intersect_p (to, GENERAL_REGS)
24983 || reg_classes_intersect_p (from, GENERAL_REGS))
24985 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24988 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24989 ret = (rs6000_memory_move_cost (mode, from, 0)
24990 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24992 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24994 else if (from == CR_REGS)
24997 /* Power6 has slower LR/CTR moves so make them more expensive than
24998 memory in order to bias spills to memory .*/
24999 else if (rs6000_cpu == PROCESSOR_POWER6
25000 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25001 ret = 6 * hard_regno_nregs[0][mode];
25004 /* A move will cost one instruction per GPR moved. */
25005 ret = 2 * hard_regno_nregs[0][mode];
25008 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25009 else if (VECTOR_UNIT_VSX_P (mode)
25010 && reg_classes_intersect_p (to, VSX_REGS)
25011 && reg_classes_intersect_p (from, VSX_REGS))
25012 ret = 2 * hard_regno_nregs[32][mode];
25014 /* Moving between two similar registers is just one instruction. */
25015 else if (reg_classes_intersect_p (to, from))
25016 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25018 /* Everything else has to go through GENERAL_REGS. */
25020 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25021 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25023 if (TARGET_DEBUG_COST)
25025 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25026 ret, GET_MODE_NAME (mode), reg_class_names[from],
25027 reg_class_names[to]);
25032 /* A C expressions returning the cost of moving data of MODE from a register to
25036 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25037 int in ATTRIBUTE_UNUSED)
25041 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25042 ret = 4 * hard_regno_nregs[0][mode];
25043 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25044 ret = 4 * hard_regno_nregs[32][mode];
25045 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25046 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25048 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25050 if (TARGET_DEBUG_COST)
25052 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25053 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25058 /* Returns a code for a target-specific builtin that implements
25059 reciprocal of the function, or NULL_TREE if not available. */
25062 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25063 bool sqrt ATTRIBUTE_UNUSED)
25065 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25066 && flag_finite_math_only && !flag_trapping_math
25067 && flag_unsafe_math_optimizations))
25075 case BUILT_IN_SQRTF:
25076 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25083 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25084 Assumes no trapping math and finite arguments. */
25087 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25089 rtx x0, e0, e1, y1, u0, v0, one;
25091 x0 = gen_reg_rtx (SFmode);
25092 e0 = gen_reg_rtx (SFmode);
25093 e1 = gen_reg_rtx (SFmode);
25094 y1 = gen_reg_rtx (SFmode);
25095 u0 = gen_reg_rtx (SFmode);
25096 v0 = gen_reg_rtx (SFmode);
25097 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25099 /* x0 = 1./d estimate */
25100 emit_insn (gen_rtx_SET (VOIDmode, x0,
25101 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25103 /* e0 = 1. - d * x0 */
25104 emit_insn (gen_rtx_SET (VOIDmode, e0,
25105 gen_rtx_MINUS (SFmode, one,
25106 gen_rtx_MULT (SFmode, d, x0))));
25107 /* e1 = e0 + e0 * e0 */
25108 emit_insn (gen_rtx_SET (VOIDmode, e1,
25109 gen_rtx_PLUS (SFmode,
25110 gen_rtx_MULT (SFmode, e0, e0), e0)));
25111 /* y1 = x0 + e1 * x0 */
25112 emit_insn (gen_rtx_SET (VOIDmode, y1,
25113 gen_rtx_PLUS (SFmode,
25114 gen_rtx_MULT (SFmode, e1, x0), x0)));
25116 emit_insn (gen_rtx_SET (VOIDmode, u0,
25117 gen_rtx_MULT (SFmode, n, y1)));
25118 /* v0 = n - d * u0 */
25119 emit_insn (gen_rtx_SET (VOIDmode, v0,
25120 gen_rtx_MINUS (SFmode, n,
25121 gen_rtx_MULT (SFmode, d, u0))));
25122 /* dst = u0 + v0 * y1 */
25123 emit_insn (gen_rtx_SET (VOIDmode, dst,
25124 gen_rtx_PLUS (SFmode,
25125 gen_rtx_MULT (SFmode, v0, y1), u0)));
25128 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25129 Assumes no trapping math and finite arguments. */
25132 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25134 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25136 x0 = gen_reg_rtx (DFmode);
25137 e0 = gen_reg_rtx (DFmode);
25138 e1 = gen_reg_rtx (DFmode);
25139 e2 = gen_reg_rtx (DFmode);
25140 y1 = gen_reg_rtx (DFmode);
25141 y2 = gen_reg_rtx (DFmode);
25142 y3 = gen_reg_rtx (DFmode);
25143 u0 = gen_reg_rtx (DFmode);
25144 v0 = gen_reg_rtx (DFmode);
25145 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25147 /* x0 = 1./d estimate */
25148 emit_insn (gen_rtx_SET (VOIDmode, x0,
25149 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25151 /* e0 = 1. - d * x0 */
25152 emit_insn (gen_rtx_SET (VOIDmode, e0,
25153 gen_rtx_MINUS (DFmode, one,
25154 gen_rtx_MULT (SFmode, d, x0))));
25155 /* y1 = x0 + e0 * x0 */
25156 emit_insn (gen_rtx_SET (VOIDmode, y1,
25157 gen_rtx_PLUS (DFmode,
25158 gen_rtx_MULT (DFmode, e0, x0), x0)));
25160 emit_insn (gen_rtx_SET (VOIDmode, e1,
25161 gen_rtx_MULT (DFmode, e0, e0)));
25162 /* y2 = y1 + e1 * y1 */
25163 emit_insn (gen_rtx_SET (VOIDmode, y2,
25164 gen_rtx_PLUS (DFmode,
25165 gen_rtx_MULT (DFmode, e1, y1), y1)));
25167 emit_insn (gen_rtx_SET (VOIDmode, e2,
25168 gen_rtx_MULT (DFmode, e1, e1)));
25169 /* y3 = y2 + e2 * y2 */
25170 emit_insn (gen_rtx_SET (VOIDmode, y3,
25171 gen_rtx_PLUS (DFmode,
25172 gen_rtx_MULT (DFmode, e2, y2), y2)));
25174 emit_insn (gen_rtx_SET (VOIDmode, u0,
25175 gen_rtx_MULT (DFmode, n, y3)));
25176 /* v0 = n - d * u0 */
25177 emit_insn (gen_rtx_SET (VOIDmode, v0,
25178 gen_rtx_MINUS (DFmode, n,
25179 gen_rtx_MULT (DFmode, d, u0))));
25180 /* dst = u0 + v0 * y3 */
25181 emit_insn (gen_rtx_SET (VOIDmode, dst,
25182 gen_rtx_PLUS (DFmode,
25183 gen_rtx_MULT (DFmode, v0, y3), u0)));
25187 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25188 Assumes no trapping math and finite arguments. */
25191 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25193 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25194 half, one, halfthree, c1, cond, label;
25196 x0 = gen_reg_rtx (SFmode);
25197 x1 = gen_reg_rtx (SFmode);
25198 x2 = gen_reg_rtx (SFmode);
25199 y1 = gen_reg_rtx (SFmode);
25200 u0 = gen_reg_rtx (SFmode);
25201 u1 = gen_reg_rtx (SFmode);
25202 u2 = gen_reg_rtx (SFmode);
25203 v0 = gen_reg_rtx (SFmode);
25204 v1 = gen_reg_rtx (SFmode);
25205 v2 = gen_reg_rtx (SFmode);
25206 t0 = gen_reg_rtx (SFmode);
25207 halfthree = gen_reg_rtx (SFmode);
25208 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25209 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25211 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25212 emit_insn (gen_rtx_SET (VOIDmode, t0,
25213 gen_rtx_MULT (SFmode, src, src)));
25215 emit_insn (gen_rtx_SET (VOIDmode, cond,
25216 gen_rtx_COMPARE (CCFPmode, t0, src)));
25217 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25218 emit_unlikely_jump (c1, label);
25220 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25221 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25223 /* halfthree = 1.5 = 1.0 + 0.5 */
25224 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25225 gen_rtx_PLUS (SFmode, one, half)));
25227 /* x0 = rsqrt estimate */
25228 emit_insn (gen_rtx_SET (VOIDmode, x0,
25229 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25232 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25233 emit_insn (gen_rtx_SET (VOIDmode, y1,
25234 gen_rtx_MINUS (SFmode,
25235 gen_rtx_MULT (SFmode, src, halfthree),
25238 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25239 emit_insn (gen_rtx_SET (VOIDmode, u0,
25240 gen_rtx_MULT (SFmode, x0, x0)));
25241 emit_insn (gen_rtx_SET (VOIDmode, v0,
25242 gen_rtx_MINUS (SFmode,
25244 gen_rtx_MULT (SFmode, y1, u0))));
25245 emit_insn (gen_rtx_SET (VOIDmode, x1,
25246 gen_rtx_MULT (SFmode, x0, v0)));
25248 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25249 emit_insn (gen_rtx_SET (VOIDmode, u1,
25250 gen_rtx_MULT (SFmode, x1, x1)));
25251 emit_insn (gen_rtx_SET (VOIDmode, v1,
25252 gen_rtx_MINUS (SFmode,
25254 gen_rtx_MULT (SFmode, y1, u1))));
25255 emit_insn (gen_rtx_SET (VOIDmode, x2,
25256 gen_rtx_MULT (SFmode, x1, v1)));
25258 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25259 emit_insn (gen_rtx_SET (VOIDmode, u2,
25260 gen_rtx_MULT (SFmode, x2, x2)));
25261 emit_insn (gen_rtx_SET (VOIDmode, v2,
25262 gen_rtx_MINUS (SFmode,
25264 gen_rtx_MULT (SFmode, y1, u2))));
25265 emit_insn (gen_rtx_SET (VOIDmode, dst,
25266 gen_rtx_MULT (SFmode, x2, v2)));
25268 emit_label (XEXP (label, 0));
25271 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25272 (Power7) targets. DST is the target, and SRC is the argument operand. */
25275 rs6000_emit_popcount (rtx dst, rtx src)
25277 enum machine_mode mode = GET_MODE (dst);
25280 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25281 if (TARGET_POPCNTD)
25283 if (mode == SImode)
25284 emit_insn (gen_popcntwsi2 (dst, src));
25286 emit_insn (gen_popcntddi2 (dst, src));
25290 tmp1 = gen_reg_rtx (mode);
25292 if (mode == SImode)
25294 emit_insn (gen_popcntbsi2 (tmp1, src));
25295 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25297 tmp2 = force_reg (SImode, tmp2);
25298 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25302 emit_insn (gen_popcntbdi2 (tmp1, src));
25303 tmp2 = expand_mult (DImode, tmp1,
25304 GEN_INT ((HOST_WIDE_INT)
25305 0x01010101 << 32 | 0x01010101),
25307 tmp2 = force_reg (DImode, tmp2);
25308 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25313 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25314 target, and SRC is the argument operand. */
25317 rs6000_emit_parity (rtx dst, rtx src)
25319 enum machine_mode mode = GET_MODE (dst);
25322 tmp = gen_reg_rtx (mode);
25323 if (mode == SImode)
25325 /* Is mult+shift >= shift+xor+shift+xor? */
25326 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25328 rtx tmp1, tmp2, tmp3, tmp4;
25330 tmp1 = gen_reg_rtx (SImode);
25331 emit_insn (gen_popcntbsi2 (tmp1, src));
25333 tmp2 = gen_reg_rtx (SImode);
25334 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25335 tmp3 = gen_reg_rtx (SImode);
25336 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25338 tmp4 = gen_reg_rtx (SImode);
25339 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25340 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25343 rs6000_emit_popcount (tmp, src);
25344 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25348 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25349 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25351 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25353 tmp1 = gen_reg_rtx (DImode);
25354 emit_insn (gen_popcntbdi2 (tmp1, src));
25356 tmp2 = gen_reg_rtx (DImode);
25357 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25358 tmp3 = gen_reg_rtx (DImode);
25359 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25361 tmp4 = gen_reg_rtx (DImode);
25362 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25363 tmp5 = gen_reg_rtx (DImode);
25364 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25366 tmp6 = gen_reg_rtx (DImode);
25367 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25368 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25371 rs6000_emit_popcount (tmp, src);
25372 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25376 /* Return an RTX representing where to find the function value of a
25377 function returning MODE. */
25379 rs6000_complex_function_value (enum machine_mode mode)
25381 unsigned int regno;
25383 enum machine_mode inner = GET_MODE_INNER (mode);
25384 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25386 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25387 regno = FP_ARG_RETURN;
25390 regno = GP_ARG_RETURN;
25392 /* 32-bit is OK since it'll go in r3/r4. */
25393 if (TARGET_32BIT && inner_bytes >= 4)
25394 return gen_rtx_REG (mode, regno);
25397 if (inner_bytes >= 8)
25398 return gen_rtx_REG (mode, regno);
25400 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25402 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25403 GEN_INT (inner_bytes));
25404 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25407 /* Target hook for TARGET_FUNCTION_VALUE.
25409 On the SPE, both FPs and vectors are returned in r3.
25411 On RS/6000 an integer value is in r3 and a floating-point value is in
25412 fp1, unless -msoft-float. */
25415 rs6000_function_value (const_tree valtype,
25416 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25417 bool outgoing ATTRIBUTE_UNUSED)
25419 enum machine_mode mode;
25420 unsigned int regno;
25422 /* Special handling for structs in darwin64. */
25423 if (rs6000_darwin64_abi
25424 && TYPE_MODE (valtype) == BLKmode
25425 && TREE_CODE (valtype) == RECORD_TYPE
25426 && int_size_in_bytes (valtype) > 0)
25428 CUMULATIVE_ARGS valcum;
25432 valcum.fregno = FP_ARG_MIN_REG;
25433 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25434 /* Do a trial code generation as if this were going to be passed as
25435 an argument; if any part goes in memory, we return NULL. */
25436 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25439 /* Otherwise fall through to standard ABI rules. */
25442 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25444 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25445 return gen_rtx_PARALLEL (DImode,
25447 gen_rtx_EXPR_LIST (VOIDmode,
25448 gen_rtx_REG (SImode, GP_ARG_RETURN),
25450 gen_rtx_EXPR_LIST (VOIDmode,
25451 gen_rtx_REG (SImode,
25452 GP_ARG_RETURN + 1),
25455 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25457 return gen_rtx_PARALLEL (DCmode,
25459 gen_rtx_EXPR_LIST (VOIDmode,
25460 gen_rtx_REG (SImode, GP_ARG_RETURN),
25462 gen_rtx_EXPR_LIST (VOIDmode,
25463 gen_rtx_REG (SImode,
25464 GP_ARG_RETURN + 1),
25466 gen_rtx_EXPR_LIST (VOIDmode,
25467 gen_rtx_REG (SImode,
25468 GP_ARG_RETURN + 2),
25470 gen_rtx_EXPR_LIST (VOIDmode,
25471 gen_rtx_REG (SImode,
25472 GP_ARG_RETURN + 3),
25476 mode = TYPE_MODE (valtype);
25477 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25478 || POINTER_TYPE_P (valtype))
25479 mode = TARGET_32BIT ? SImode : DImode;
25481 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25482 /* _Decimal128 must use an even/odd register pair. */
25483 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25484 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25485 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25486 regno = FP_ARG_RETURN;
25487 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25488 && targetm.calls.split_complex_arg)
25489 return rs6000_complex_function_value (mode);
25490 else if (TREE_CODE (valtype) == VECTOR_TYPE
25491 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25492 && ALTIVEC_VECTOR_MODE (mode))
25493 regno = ALTIVEC_ARG_RETURN;
25494 else if (TREE_CODE (valtype) == VECTOR_TYPE
25495 && TARGET_VSX && TARGET_ALTIVEC_ABI
25496 && VSX_VECTOR_MODE (mode))
25497 regno = ALTIVEC_ARG_RETURN;
25498 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25499 && (mode == DFmode || mode == DCmode
25500 || mode == TFmode || mode == TCmode))
25501 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25503 regno = GP_ARG_RETURN;
25505 return gen_rtx_REG (mode, regno);
25508 /* Define how to find the value returned by a library function
25509 assuming the value has mode MODE. */
25511 rs6000_libcall_value (enum machine_mode mode)
25513 unsigned int regno;
25515 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25517 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25518 return gen_rtx_PARALLEL (DImode,
25520 gen_rtx_EXPR_LIST (VOIDmode,
25521 gen_rtx_REG (SImode, GP_ARG_RETURN),
25523 gen_rtx_EXPR_LIST (VOIDmode,
25524 gen_rtx_REG (SImode,
25525 GP_ARG_RETURN + 1),
25529 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25530 /* _Decimal128 must use an even/odd register pair. */
25531 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25532 else if (SCALAR_FLOAT_MODE_P (mode)
25533 && TARGET_HARD_FLOAT && TARGET_FPRS
25534 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25535 regno = FP_ARG_RETURN;
25536 else if (ALTIVEC_VECTOR_MODE (mode)
25537 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25538 regno = ALTIVEC_ARG_RETURN;
25539 else if (VSX_VECTOR_MODE (mode)
25540 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25541 regno = ALTIVEC_ARG_RETURN;
25542 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25543 return rs6000_complex_function_value (mode);
25544 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25545 && (mode == DFmode || mode == DCmode
25546 || mode == TFmode || mode == TCmode))
25547 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25549 regno = GP_ARG_RETURN;
25551 return gen_rtx_REG (mode, regno);
25555 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25556 Frame pointer elimination is automatically handled.
25558 For the RS/6000, if frame pointer elimination is being done, we would like
25559 to convert ap into fp, not sp.
25561 We need r30 if -mminimal-toc was specified, and there are constant pool
25565 rs6000_can_eliminate (const int from, const int to)
25567 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25568 ? ! frame_pointer_needed
25569 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25570 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25574 /* Define the offset between two registers, FROM to be eliminated and its
25575 replacement TO, at the start of a routine. */
25577 rs6000_initial_elimination_offset (int from, int to)
25579 rs6000_stack_t *info = rs6000_stack_info ();
25580 HOST_WIDE_INT offset;
25582 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25583 offset = info->push_p ? 0 : -info->total_size;
25584 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25586 offset = info->push_p ? 0 : -info->total_size;
25587 if (FRAME_GROWS_DOWNWARD)
25588 offset += info->fixed_size + info->vars_size + info->parm_size;
25590 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25591 offset = FRAME_GROWS_DOWNWARD
25592 ? info->fixed_size + info->vars_size + info->parm_size
25594 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25595 offset = info->total_size;
25596 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25597 offset = info->push_p ? info->total_size : 0;
25598 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25601 gcc_unreachable ();
25607 rs6000_dwarf_register_span (rtx reg)
25611 unsigned regno = REGNO (reg);
25612 enum machine_mode mode = GET_MODE (reg);
25616 && (SPE_VECTOR_MODE (GET_MODE (reg))
25617 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25618 && mode != SFmode && mode != SDmode && mode != SCmode)))
25623 regno = REGNO (reg);
25625 /* The duality of the SPE register size wreaks all kinds of havoc.
25626 This is a way of distinguishing r0 in 32-bits from r0 in
25628 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25629 gcc_assert (words <= 4);
25630 for (i = 0; i < words; i++, regno++)
25632 if (BYTES_BIG_ENDIAN)
25634 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25635 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25639 parts[2 * i] = gen_rtx_REG (SImode, regno);
25640 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25644 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25647 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25650 rs6000_init_dwarf_reg_sizes_extra (tree address)
25655 enum machine_mode mode = TYPE_MODE (char_type_node);
25656 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25657 rtx mem = gen_rtx_MEM (BLKmode, addr);
25658 rtx value = gen_int_mode (4, mode);
25660 for (i = 1201; i < 1232; i++)
25662 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25663 HOST_WIDE_INT offset
25664 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25666 emit_move_insn (adjust_address (mem, mode, offset), value);
25671 /* Map internal gcc register numbers to DWARF2 register numbers. */
25674 rs6000_dbx_register_number (unsigned int regno)
25676 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25678 if (regno == MQ_REGNO)
25680 if (regno == LR_REGNO)
25682 if (regno == CTR_REGNO)
25684 if (CR_REGNO_P (regno))
25685 return regno - CR0_REGNO + 86;
25686 if (regno == XER_REGNO)
25688 if (ALTIVEC_REGNO_P (regno))
25689 return regno - FIRST_ALTIVEC_REGNO + 1124;
25690 if (regno == VRSAVE_REGNO)
25692 if (regno == VSCR_REGNO)
25694 if (regno == SPE_ACC_REGNO)
25696 if (regno == SPEFSCR_REGNO)
25698 /* SPE high reg number. We get these values of regno from
25699 rs6000_dwarf_register_span. */
25700 gcc_assert (regno >= 1200 && regno < 1232);
25704 /* target hook eh_return_filter_mode */
25705 static enum machine_mode
25706 rs6000_eh_return_filter_mode (void)
25708 return TARGET_32BIT ? SImode : word_mode;
25711 /* Target hook for scalar_mode_supported_p. */
25713 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25715 if (DECIMAL_FLOAT_MODE_P (mode))
25716 return default_decimal_float_supported_p ();
25718 return default_scalar_mode_supported_p (mode);
25721 /* Target hook for vector_mode_supported_p. */
25723 rs6000_vector_mode_supported_p (enum machine_mode mode)
25726 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25729 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25732 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25739 /* Target hook for invalid_arg_for_unprototyped_fn. */
25740 static const char *
25741 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25743 return (!rs6000_darwin64_abi
25745 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25746 && (funcdecl == NULL_TREE
25747 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25748 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25749 ? N_("AltiVec argument passed to unprototyped function")
25753 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25754 setup by using __stack_chk_fail_local hidden function instead of
25755 calling __stack_chk_fail directly. Otherwise it is better to call
25756 __stack_chk_fail directly. */
25759 rs6000_stack_protect_fail (void)
25761 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25762 ? default_hidden_stack_protect_fail ()
25763 : default_external_stack_protect_fail ();
25767 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25768 int num_operands ATTRIBUTE_UNUSED)
25770 if (rs6000_warn_cell_microcode)
25773 int insn_code_number = recog_memoized (insn);
25774 location_t location = locator_location (INSN_LOCATOR (insn));
25776 /* Punt on insns we cannot recognize. */
25777 if (insn_code_number < 0)
25780 temp = get_insn_template (insn_code_number, insn);
25782 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25783 warning_at (location, OPT_mwarn_cell_microcode,
25784 "emitting microcode insn %s\t[%s] #%d",
25785 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25786 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25787 warning_at (location, OPT_mwarn_cell_microcode,
25788 "emitting conditional microcode insn %s\t[%s] #%d",
25789 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25793 #include "gt-rs6000.h"