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
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
257 traceback_default = 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC476 processors. */
516 struct processor_costs ppc476_cost = {
517 COSTS_N_INSNS (4), /* mulsi */
518 COSTS_N_INSNS (4), /* mulsi_const */
519 COSTS_N_INSNS (4), /* mulsi_const9 */
520 COSTS_N_INSNS (4), /* muldi */
521 COSTS_N_INSNS (11), /* divsi */
522 COSTS_N_INSNS (11), /* divdi */
523 COSTS_N_INSNS (6), /* fp */
524 COSTS_N_INSNS (6), /* dmul */
525 COSTS_N_INSNS (19), /* sdiv */
526 COSTS_N_INSNS (33), /* ddiv */
527 32, /* l1 cache line size */
533 /* Instruction costs on PPC601 processors. */
535 struct processor_costs ppc601_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (5), /* mulsi_const */
538 COSTS_N_INSNS (5), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (36), /* divsi */
541 COSTS_N_INSNS (36), /* divdi */
542 COSTS_N_INSNS (4), /* fp */
543 COSTS_N_INSNS (5), /* dmul */
544 COSTS_N_INSNS (17), /* sdiv */
545 COSTS_N_INSNS (31), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC603 processors. */
554 struct processor_costs ppc603_cost = {
555 COSTS_N_INSNS (5), /* mulsi */
556 COSTS_N_INSNS (3), /* mulsi_const */
557 COSTS_N_INSNS (2), /* mulsi_const9 */
558 COSTS_N_INSNS (5), /* muldi */
559 COSTS_N_INSNS (37), /* divsi */
560 COSTS_N_INSNS (37), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (4), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (33), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604 processors. */
573 struct processor_costs ppc604_cost = {
574 COSTS_N_INSNS (4), /* mulsi */
575 COSTS_N_INSNS (4), /* mulsi_const */
576 COSTS_N_INSNS (4), /* mulsi_const9 */
577 COSTS_N_INSNS (4), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC604e processors. */
592 struct processor_costs ppc604e_cost = {
593 COSTS_N_INSNS (2), /* mulsi */
594 COSTS_N_INSNS (2), /* mulsi_const */
595 COSTS_N_INSNS (2), /* mulsi_const9 */
596 COSTS_N_INSNS (2), /* muldi */
597 COSTS_N_INSNS (20), /* divsi */
598 COSTS_N_INSNS (20), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 32, /* cache line size */
609 /* Instruction costs on PPC620 processors. */
611 struct processor_costs ppc620_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (18), /* sdiv */
621 COSTS_N_INSNS (32), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on PPC630 processors. */
630 struct processor_costs ppc630_cost = {
631 COSTS_N_INSNS (5), /* mulsi */
632 COSTS_N_INSNS (4), /* mulsi_const */
633 COSTS_N_INSNS (3), /* mulsi_const9 */
634 COSTS_N_INSNS (7), /* muldi */
635 COSTS_N_INSNS (21), /* divsi */
636 COSTS_N_INSNS (37), /* divdi */
637 COSTS_N_INSNS (3), /* fp */
638 COSTS_N_INSNS (3), /* dmul */
639 COSTS_N_INSNS (17), /* sdiv */
640 COSTS_N_INSNS (21), /* ddiv */
641 128, /* cache line size */
647 /* Instruction costs on Cell processor. */
648 /* COSTS_N_INSNS (1) ~ one add. */
650 struct processor_costs ppccell_cost = {
651 COSTS_N_INSNS (9/2)+2, /* mulsi */
652 COSTS_N_INSNS (6/2), /* mulsi_const */
653 COSTS_N_INSNS (6/2), /* mulsi_const9 */
654 COSTS_N_INSNS (15/2)+2, /* muldi */
655 COSTS_N_INSNS (38/2), /* divsi */
656 COSTS_N_INSNS (70/2), /* divdi */
657 COSTS_N_INSNS (10/2), /* fp */
658 COSTS_N_INSNS (10/2), /* dmul */
659 COSTS_N_INSNS (74/2), /* sdiv */
660 COSTS_N_INSNS (74/2), /* ddiv */
661 128, /* cache line size */
667 /* Instruction costs on PPC750 and PPC7400 processors. */
669 struct processor_costs ppc750_cost = {
670 COSTS_N_INSNS (5), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (2), /* mulsi_const9 */
673 COSTS_N_INSNS (5), /* muldi */
674 COSTS_N_INSNS (17), /* divsi */
675 COSTS_N_INSNS (17), /* divdi */
676 COSTS_N_INSNS (3), /* fp */
677 COSTS_N_INSNS (3), /* dmul */
678 COSTS_N_INSNS (17), /* sdiv */
679 COSTS_N_INSNS (31), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC7450 processors. */
688 struct processor_costs ppc7450_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (3), /* mulsi_const */
691 COSTS_N_INSNS (3), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (23), /* divsi */
694 COSTS_N_INSNS (23), /* divdi */
695 COSTS_N_INSNS (5), /* fp */
696 COSTS_N_INSNS (5), /* dmul */
697 COSTS_N_INSNS (21), /* sdiv */
698 COSTS_N_INSNS (35), /* ddiv */
699 32, /* cache line size */
705 /* Instruction costs on PPC8540 processors. */
707 struct processor_costs ppc8540_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (4), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (29), /* sdiv */
717 COSTS_N_INSNS (29), /* ddiv */
718 32, /* cache line size */
721 1, /* prefetch streams /*/
724 /* Instruction costs on E300C2 and E300C3 cores. */
726 struct processor_costs ppce300c2c3_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (19), /* divsi */
732 COSTS_N_INSNS (19), /* divdi */
733 COSTS_N_INSNS (3), /* fp */
734 COSTS_N_INSNS (4), /* dmul */
735 COSTS_N_INSNS (18), /* sdiv */
736 COSTS_N_INSNS (33), /* ddiv */
740 1, /* prefetch streams /*/
743 /* Instruction costs on PPCE500MC processors. */
745 struct processor_costs ppce500mc_cost = {
746 COSTS_N_INSNS (4), /* mulsi */
747 COSTS_N_INSNS (4), /* mulsi_const */
748 COSTS_N_INSNS (4), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (14), /* divsi */
751 COSTS_N_INSNS (14), /* divdi */
752 COSTS_N_INSNS (8), /* fp */
753 COSTS_N_INSNS (10), /* dmul */
754 COSTS_N_INSNS (36), /* sdiv */
755 COSTS_N_INSNS (66), /* ddiv */
756 64, /* cache line size */
759 1, /* prefetch streams /*/
762 /* Instruction costs on PPCE500MC64 processors. */
764 struct processor_costs ppce500mc64_cost = {
765 COSTS_N_INSNS (4), /* mulsi */
766 COSTS_N_INSNS (4), /* mulsi_const */
767 COSTS_N_INSNS (4), /* mulsi_const9 */
768 COSTS_N_INSNS (4), /* muldi */
769 COSTS_N_INSNS (14), /* divsi */
770 COSTS_N_INSNS (14), /* divdi */
771 COSTS_N_INSNS (4), /* fp */
772 COSTS_N_INSNS (10), /* dmul */
773 COSTS_N_INSNS (36), /* sdiv */
774 COSTS_N_INSNS (66), /* ddiv */
775 64, /* cache line size */
778 1, /* prefetch streams /*/
781 /* Instruction costs on POWER4 and POWER5 processors. */
783 struct processor_costs power4_cost = {
784 COSTS_N_INSNS (3), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (4), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (17), /* sdiv */
793 COSTS_N_INSNS (17), /* ddiv */
794 128, /* cache line size */
797 8, /* prefetch streams /*/
800 /* Instruction costs on POWER6 processors. */
802 struct processor_costs power6_cost = {
803 COSTS_N_INSNS (8), /* mulsi */
804 COSTS_N_INSNS (8), /* mulsi_const */
805 COSTS_N_INSNS (8), /* mulsi_const9 */
806 COSTS_N_INSNS (8), /* muldi */
807 COSTS_N_INSNS (22), /* divsi */
808 COSTS_N_INSNS (28), /* divdi */
809 COSTS_N_INSNS (3), /* fp */
810 COSTS_N_INSNS (3), /* dmul */
811 COSTS_N_INSNS (13), /* sdiv */
812 COSTS_N_INSNS (16), /* ddiv */
813 128, /* cache line size */
816 16, /* prefetch streams */
819 /* Instruction costs on POWER7 processors. */
821 struct processor_costs power7_cost = {
822 COSTS_N_INSNS (2), /* mulsi */
823 COSTS_N_INSNS (2), /* mulsi_const */
824 COSTS_N_INSNS (2), /* mulsi_const9 */
825 COSTS_N_INSNS (2), /* muldi */
826 COSTS_N_INSNS (18), /* divsi */
827 COSTS_N_INSNS (34), /* divdi */
828 COSTS_N_INSNS (3), /* fp */
829 COSTS_N_INSNS (3), /* dmul */
830 COSTS_N_INSNS (13), /* sdiv */
831 COSTS_N_INSNS (16), /* ddiv */
832 128, /* cache line size */
835 12, /* prefetch streams */
838 /* Instruction costs on POWER A2 processors. */
840 struct processor_costs ppca2_cost = {
841 COSTS_N_INSNS (16), /* mulsi */
842 COSTS_N_INSNS (16), /* mulsi_const */
843 COSTS_N_INSNS (16), /* mulsi_const9 */
844 COSTS_N_INSNS (16), /* muldi */
845 COSTS_N_INSNS (22), /* divsi */
846 COSTS_N_INSNS (28), /* divdi */
847 COSTS_N_INSNS (3), /* fp */
848 COSTS_N_INSNS (3), /* dmul */
849 COSTS_N_INSNS (59), /* sdiv */
850 COSTS_N_INSNS (72), /* ddiv */
854 16, /* prefetch streams */
858 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
859 #undef RS6000_BUILTIN
860 #undef RS6000_BUILTIN_EQUATE
861 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
862 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
864 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
866 #include "rs6000-builtin.def"
869 #undef RS6000_BUILTIN
870 #undef RS6000_BUILTIN_EQUATE
873 static bool rs6000_function_ok_for_sibcall (tree, tree);
874 static const char *rs6000_invalid_within_doloop (const_rtx);
875 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
876 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
877 static rtx rs6000_generate_compare (rtx, enum machine_mode);
878 static void rs6000_emit_stack_tie (void);
879 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
880 static bool spe_func_has_64bit_regs_p (void);
881 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
883 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
884 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
885 static unsigned rs6000_hash_constant (rtx);
886 static unsigned toc_hash_function (const void *);
887 static int toc_hash_eq (const void *, const void *);
888 static bool reg_offset_addressing_ok_p (enum machine_mode);
889 static bool virtual_stack_registers_memory_p (rtx);
890 static bool constant_pool_expr_p (rtx);
891 static bool legitimate_small_data_p (enum machine_mode, rtx);
892 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
893 static struct machine_function * rs6000_init_machine_status (void);
894 static bool rs6000_assemble_integer (rtx, unsigned int, int);
895 static bool no_global_regs_above (int, bool);
896 #ifdef HAVE_GAS_HIDDEN
897 static void rs6000_assemble_visibility (tree, int);
899 static int rs6000_ra_ever_killed (void);
900 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
901 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
902 static bool rs6000_ms_bitfield_layout_p (const_tree);
903 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
904 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
905 static const char *rs6000_mangle_type (const_tree);
906 static void rs6000_set_default_type_attributes (tree);
907 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
908 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
909 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
910 enum machine_mode, bool, bool, bool);
911 static bool rs6000_reg_live_or_pic_offset_p (int);
912 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
913 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
914 static void rs6000_restore_saved_cr (rtx, int);
915 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
916 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
917 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
919 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
920 static bool rs6000_return_in_memory (const_tree, const_tree);
921 static rtx rs6000_function_value (const_tree, const_tree, bool);
922 static void rs6000_file_start (void);
924 static int rs6000_elf_reloc_rw_mask (void);
925 static void rs6000_elf_asm_out_constructor (rtx, int);
926 static void rs6000_elf_asm_out_destructor (rtx, int);
927 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
928 static void rs6000_elf_asm_init_sections (void);
929 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
930 unsigned HOST_WIDE_INT);
931 static void rs6000_elf_encode_section_info (tree, rtx, int)
934 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
935 static void rs6000_alloc_sdmode_stack_slot (void);
936 static void rs6000_instantiate_decls (void);
938 static void rs6000_xcoff_asm_output_anchor (rtx);
939 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
940 static void rs6000_xcoff_asm_init_sections (void);
941 static int rs6000_xcoff_reloc_rw_mask (void);
942 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
943 static section *rs6000_xcoff_select_section (tree, int,
944 unsigned HOST_WIDE_INT);
945 static void rs6000_xcoff_unique_section (tree, int);
946 static section *rs6000_xcoff_select_rtx_section
947 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
948 static const char * rs6000_xcoff_strip_name_encoding (const char *);
949 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
950 static void rs6000_xcoff_file_start (void);
951 static void rs6000_xcoff_file_end (void);
953 static int rs6000_variable_issue (FILE *, int, rtx, int);
954 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
955 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
956 static int rs6000_debug_address_cost (rtx, bool);
957 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
958 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
959 static void rs6000_sched_init (FILE *, int, int);
960 static bool is_microcoded_insn (rtx);
961 static bool is_nonpipeline_insn (rtx);
962 static bool is_cracked_insn (rtx);
963 static bool is_branch_slot_insn (rtx);
964 static bool is_load_insn (rtx);
965 static rtx get_store_dest (rtx pat);
966 static bool is_store_insn (rtx);
967 static bool set_to_load_agen (rtx,rtx);
968 static bool adjacent_mem_locations (rtx,rtx);
969 static int rs6000_adjust_priority (rtx, int);
970 static int rs6000_issue_rate (void);
971 static bool rs6000_is_costly_dependence (dep_t, int, int);
972 static rtx get_next_active_insn (rtx, rtx);
973 static bool insn_terminates_group_p (rtx , enum group_termination);
974 static bool insn_must_be_first_in_group (rtx);
975 static bool insn_must_be_last_in_group (rtx);
976 static bool is_costly_group (rtx *, rtx);
977 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
978 static int redefine_groups (FILE *, int, rtx, rtx);
979 static int pad_groups (FILE *, int, rtx, rtx);
980 static void rs6000_sched_finish (FILE *, int);
981 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
982 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
983 static int rs6000_use_sched_lookahead (void);
984 static int rs6000_use_sched_lookahead_guard (rtx);
985 static void * rs6000_alloc_sched_context (void);
986 static void rs6000_init_sched_context (void *, bool);
987 static void rs6000_set_sched_context (void *);
988 static void rs6000_free_sched_context (void *);
989 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
990 static tree rs6000_builtin_mask_for_load (void);
991 static tree rs6000_builtin_mul_widen_even (tree);
992 static tree rs6000_builtin_mul_widen_odd (tree);
993 static tree rs6000_builtin_conversion (unsigned int, tree);
994 static tree rs6000_builtin_vec_perm (tree, tree *);
995 static bool rs6000_builtin_support_vector_misalignment (enum
1000 static void def_builtin (int, const char *, tree, int);
1001 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1002 static void rs6000_init_builtins (void);
1003 static tree rs6000_builtin_decl (unsigned, bool);
1005 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1006 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1007 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1008 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1009 static void altivec_init_builtins (void);
1010 static unsigned builtin_hash_function (const void *);
1011 static int builtin_hash_eq (const void *, const void *);
1012 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1013 enum machine_mode, enum machine_mode,
1014 enum rs6000_builtins, const char *name);
1015 static void rs6000_common_init_builtins (void);
1016 static void rs6000_init_libfuncs (void);
1018 static void paired_init_builtins (void);
1019 static rtx paired_expand_builtin (tree, rtx, bool *);
1020 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1021 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1022 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1024 static void enable_mask_for_builtins (struct builtin_description *, int,
1025 enum rs6000_builtins,
1026 enum rs6000_builtins);
1027 static void spe_init_builtins (void);
1028 static rtx spe_expand_builtin (tree, rtx, bool *);
1029 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1030 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1031 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1032 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1033 static rs6000_stack_t *rs6000_stack_info (void);
1034 static void debug_stack_info (rs6000_stack_t *);
1036 static rtx altivec_expand_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1038 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1039 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1041 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1042 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1043 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1044 static rtx altivec_expand_vec_set_builtin (tree);
1045 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1046 static int get_element_number (tree, tree);
1047 static bool rs6000_handle_option (size_t, const char *, int);
1048 static void rs6000_parse_tls_size_option (void);
1049 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1050 static int first_altivec_reg_to_save (void);
1051 static unsigned int compute_vrsave_mask (void);
1052 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1053 static void is_altivec_return_reg (rtx, void *);
1054 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1055 int easy_vector_constant (rtx, enum machine_mode);
1056 static rtx rs6000_dwarf_register_span (rtx);
1057 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1058 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1059 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1060 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1061 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1062 static rtx rs6000_tls_get_addr (void);
1063 static rtx rs6000_got_sym (void);
1064 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1065 static const char *rs6000_get_some_local_dynamic_name (void);
1066 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1067 static rtx rs6000_complex_function_value (enum machine_mode);
1068 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1069 enum machine_mode, tree);
1070 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1072 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1073 tree, HOST_WIDE_INT);
1074 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1077 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1078 const_tree, HOST_WIDE_INT,
1080 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1081 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1082 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1083 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1084 enum machine_mode, tree,
1086 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1088 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1090 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1092 static void macho_branch_islands (void);
1093 static int no_previous_def (tree function_name);
1094 static tree get_prev_label (tree function_name);
1095 static void rs6000_darwin_file_start (void);
1098 static tree rs6000_build_builtin_va_list (void);
1099 static void rs6000_va_start (tree, rtx);
1100 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1101 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1102 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1103 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1104 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1105 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1107 static tree rs6000_stack_protect_fail (void);
1109 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1112 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1115 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1117 = rs6000_legitimize_reload_address;
1119 static bool rs6000_mode_dependent_address (rtx);
1120 static bool rs6000_debug_mode_dependent_address (rtx);
1121 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1122 = rs6000_mode_dependent_address;
1124 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1125 enum machine_mode, rtx);
1126 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1129 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1130 enum machine_mode, rtx)
1131 = rs6000_secondary_reload_class;
1133 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1134 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1136 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1137 = rs6000_preferred_reload_class;
1139 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1142 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1146 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1148 = rs6000_secondary_memory_needed;
1150 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1153 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1157 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1160 = rs6000_cannot_change_mode_class;
1162 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1164 struct secondary_reload_info *);
1166 static const enum reg_class *rs6000_ira_cover_classes (void);
1168 const int INSN_NOT_AVAILABLE = -1;
1169 static enum machine_mode rs6000_eh_return_filter_mode (void);
1170 static bool rs6000_can_eliminate (const int, const int);
1171 static void rs6000_trampoline_init (rtx, tree, rtx);
1173 /* Hash table stuff for keeping track of TOC entries. */
1175 struct GTY(()) toc_hash_struct
1177 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1178 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1180 enum machine_mode key_mode;
1184 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1186 /* Hash table to keep track of the argument types for builtin functions. */
1188 struct GTY(()) builtin_hash_struct
1191 enum machine_mode mode[4]; /* return value + 3 arguments. */
1192 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1195 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1197 /* Default register names. */
1198 char rs6000_reg_names[][8] =
1200 "0", "1", "2", "3", "4", "5", "6", "7",
1201 "8", "9", "10", "11", "12", "13", "14", "15",
1202 "16", "17", "18", "19", "20", "21", "22", "23",
1203 "24", "25", "26", "27", "28", "29", "30", "31",
1204 "0", "1", "2", "3", "4", "5", "6", "7",
1205 "8", "9", "10", "11", "12", "13", "14", "15",
1206 "16", "17", "18", "19", "20", "21", "22", "23",
1207 "24", "25", "26", "27", "28", "29", "30", "31",
1208 "mq", "lr", "ctr","ap",
1209 "0", "1", "2", "3", "4", "5", "6", "7",
1211 /* AltiVec registers. */
1212 "0", "1", "2", "3", "4", "5", "6", "7",
1213 "8", "9", "10", "11", "12", "13", "14", "15",
1214 "16", "17", "18", "19", "20", "21", "22", "23",
1215 "24", "25", "26", "27", "28", "29", "30", "31",
1217 /* SPE registers. */
1218 "spe_acc", "spefscr",
1219 /* Soft frame pointer. */
1223 #ifdef TARGET_REGNAMES
1224 static const char alt_reg_names[][8] =
1226 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1227 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1228 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1229 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1230 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1231 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1232 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1233 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1234 "mq", "lr", "ctr", "ap",
1235 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1237 /* AltiVec registers. */
1238 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1239 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1240 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1241 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1243 /* SPE registers. */
1244 "spe_acc", "spefscr",
1245 /* Soft frame pointer. */
1250 /* Table of valid machine attributes. */
1252 static const struct attribute_spec rs6000_attribute_table[] =
1254 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1255 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1256 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1257 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1258 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1259 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1260 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1261 SUBTARGET_ATTRIBUTE_TABLE,
1263 { NULL, 0, 0, false, false, false, NULL }
1266 #ifndef MASK_STRICT_ALIGN
1267 #define MASK_STRICT_ALIGN 0
1269 #ifndef TARGET_PROFILE_KERNEL
1270 #define TARGET_PROFILE_KERNEL 0
1271 #define SET_PROFILE_KERNEL(N)
1273 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1276 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1277 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1279 /* Initialize the GCC target structure. */
1280 #undef TARGET_ATTRIBUTE_TABLE
1281 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1282 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1283 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1285 #undef TARGET_ASM_ALIGNED_DI_OP
1286 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1288 /* Default unaligned ops are only provided for ELF. Find the ops needed
1289 for non-ELF systems. */
1290 #ifndef OBJECT_FORMAT_ELF
1292 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1294 #undef TARGET_ASM_UNALIGNED_HI_OP
1295 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1296 #undef TARGET_ASM_UNALIGNED_SI_OP
1297 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1298 #undef TARGET_ASM_UNALIGNED_DI_OP
1299 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1302 #undef TARGET_ASM_UNALIGNED_HI_OP
1303 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1304 #undef TARGET_ASM_UNALIGNED_SI_OP
1305 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1306 #undef TARGET_ASM_UNALIGNED_DI_OP
1307 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1308 #undef TARGET_ASM_ALIGNED_DI_OP
1309 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1313 /* This hook deals with fixups for relocatable code and DI-mode objects
1315 #undef TARGET_ASM_INTEGER
1316 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1318 #ifdef HAVE_GAS_HIDDEN
1319 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1320 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1323 #undef TARGET_HAVE_TLS
1324 #define TARGET_HAVE_TLS HAVE_AS_TLS
1326 #undef TARGET_CANNOT_FORCE_CONST_MEM
1327 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1329 #undef TARGET_ASM_FUNCTION_PROLOGUE
1330 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1331 #undef TARGET_ASM_FUNCTION_EPILOGUE
1332 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1334 #undef TARGET_LEGITIMIZE_ADDRESS
1335 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1337 #undef TARGET_SCHED_VARIABLE_ISSUE
1338 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1340 #undef TARGET_SCHED_ISSUE_RATE
1341 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1342 #undef TARGET_SCHED_ADJUST_COST
1343 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1344 #undef TARGET_SCHED_ADJUST_PRIORITY
1345 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1346 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1347 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1348 #undef TARGET_SCHED_INIT
1349 #define TARGET_SCHED_INIT rs6000_sched_init
1350 #undef TARGET_SCHED_FINISH
1351 #define TARGET_SCHED_FINISH rs6000_sched_finish
1352 #undef TARGET_SCHED_REORDER
1353 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1354 #undef TARGET_SCHED_REORDER2
1355 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1357 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1358 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1360 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1361 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1363 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1364 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1365 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1366 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1367 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1368 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1369 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1370 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1372 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1373 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1374 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1375 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1376 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1377 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1378 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1379 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1380 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1381 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1382 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1383 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1384 rs6000_builtin_support_vector_misalignment
1385 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1386 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1388 #undef TARGET_INIT_BUILTINS
1389 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1390 #undef TARGET_BUILTIN_DECL
1391 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1393 #undef TARGET_EXPAND_BUILTIN
1394 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1396 #undef TARGET_MANGLE_TYPE
1397 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1399 #undef TARGET_INIT_LIBFUNCS
1400 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1403 #undef TARGET_BINDS_LOCAL_P
1404 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1407 #undef TARGET_MS_BITFIELD_LAYOUT_P
1408 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1410 #undef TARGET_ASM_OUTPUT_MI_THUNK
1411 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1413 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1414 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1416 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1417 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1419 #undef TARGET_INVALID_WITHIN_DOLOOP
1420 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1422 #undef TARGET_RTX_COSTS
1423 #define TARGET_RTX_COSTS rs6000_rtx_costs
1424 #undef TARGET_ADDRESS_COST
1425 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1427 #undef TARGET_DWARF_REGISTER_SPAN
1428 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1430 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1431 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1433 /* On rs6000, function arguments are promoted, as are function return
1435 #undef TARGET_PROMOTE_FUNCTION_MODE
1436 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1438 #undef TARGET_RETURN_IN_MEMORY
1439 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1441 #undef TARGET_SETUP_INCOMING_VARARGS
1442 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1444 /* Always strict argument naming on rs6000. */
1445 #undef TARGET_STRICT_ARGUMENT_NAMING
1446 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1447 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1448 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1449 #undef TARGET_SPLIT_COMPLEX_ARG
1450 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1451 #undef TARGET_MUST_PASS_IN_STACK
1452 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1453 #undef TARGET_PASS_BY_REFERENCE
1454 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1455 #undef TARGET_ARG_PARTIAL_BYTES
1456 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1458 #undef TARGET_BUILD_BUILTIN_VA_LIST
1459 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1461 #undef TARGET_EXPAND_BUILTIN_VA_START
1462 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1464 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1465 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1467 #undef TARGET_EH_RETURN_FILTER_MODE
1468 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1470 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1471 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1473 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1474 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1476 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1477 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1479 #undef TARGET_HANDLE_OPTION
1480 #define TARGET_HANDLE_OPTION rs6000_handle_option
1482 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1483 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1484 rs6000_builtin_vectorized_function
1486 #undef TARGET_DEFAULT_TARGET_FLAGS
1487 #define TARGET_DEFAULT_TARGET_FLAGS \
1490 #undef TARGET_STACK_PROTECT_FAIL
1491 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1493 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1494 The PowerPC architecture requires only weak consistency among
1495 processors--that is, memory accesses between processors need not be
1496 sequentially consistent and memory accesses among processors can occur
1497 in any order. The ability to order memory accesses weakly provides
1498 opportunities for more efficient use of the system bus. Unless a
1499 dependency exists, the 604e allows read operations to precede store
1501 #undef TARGET_RELAXED_ORDERING
1502 #define TARGET_RELAXED_ORDERING true
1505 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1506 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1509 /* Use a 32-bit anchor range. This leads to sequences like:
1511 addis tmp,anchor,high
1514 where tmp itself acts as an anchor, and can be shared between
1515 accesses to the same 64k page. */
1516 #undef TARGET_MIN_ANCHOR_OFFSET
1517 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1518 #undef TARGET_MAX_ANCHOR_OFFSET
1519 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1520 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1521 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1523 #undef TARGET_BUILTIN_RECIPROCAL
1524 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1526 #undef TARGET_EXPAND_TO_RTL_HOOK
1527 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1529 #undef TARGET_INSTANTIATE_DECLS
1530 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1532 #undef TARGET_SECONDARY_RELOAD
1533 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1535 #undef TARGET_IRA_COVER_CLASSES
1536 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1538 #undef TARGET_LEGITIMATE_ADDRESS_P
1539 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1541 #undef TARGET_CAN_ELIMINATE
1542 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1544 #undef TARGET_TRAMPOLINE_INIT
1545 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1547 #undef TARGET_FUNCTION_VALUE
1548 #define TARGET_FUNCTION_VALUE rs6000_function_value
1550 struct gcc_target targetm = TARGET_INITIALIZER;
1552 /* Return number of consecutive hard regs needed starting at reg REGNO
1553 to hold something of mode MODE.
1554 This is ordinarily the length in words of a value of mode MODE
1555 but can be less for certain modes in special long registers.
1557 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1558 scalar instructions. The upper 32 bits are only available to the
1561 POWER and PowerPC GPRs hold 32 bits worth;
1562 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1565 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1567 unsigned HOST_WIDE_INT reg_size;
1569 if (FP_REGNO_P (regno))
1570 reg_size = (VECTOR_MEM_VSX_P (mode)
1571 ? UNITS_PER_VSX_WORD
1572 : UNITS_PER_FP_WORD);
1574 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1575 reg_size = UNITS_PER_SPE_WORD;
1577 else if (ALTIVEC_REGNO_P (regno))
1578 reg_size = UNITS_PER_ALTIVEC_WORD;
1580 /* The value returned for SCmode in the E500 double case is 2 for
1581 ABI compatibility; storing an SCmode value in a single register
1582 would require function_arg and rs6000_spe_function_arg to handle
1583 SCmode so as to pass the value correctly in a pair of
1585 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1586 && !DECIMAL_FLOAT_MODE_P (mode))
1587 reg_size = UNITS_PER_FP_WORD;
1590 reg_size = UNITS_PER_WORD;
1592 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1595 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1598 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1600 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1602 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1603 implementations. Don't allow an item to be split between a FP register
1604 and an Altivec register. */
1605 if (VECTOR_MEM_VSX_P (mode))
1607 if (FP_REGNO_P (regno))
1608 return FP_REGNO_P (last_regno);
1610 if (ALTIVEC_REGNO_P (regno))
1611 return ALTIVEC_REGNO_P (last_regno);
1614 /* The GPRs can hold any mode, but values bigger than one register
1615 cannot go past R31. */
1616 if (INT_REGNO_P (regno))
1617 return INT_REGNO_P (last_regno);
1619 /* The float registers (except for VSX vector modes) can only hold floating
1620 modes and DImode. This excludes the 32-bit decimal float mode for
1622 if (FP_REGNO_P (regno))
1624 if (SCALAR_FLOAT_MODE_P (mode)
1625 && (mode != TDmode || (regno % 2) == 0)
1626 && FP_REGNO_P (last_regno))
1629 if (GET_MODE_CLASS (mode) == MODE_INT
1630 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1633 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1634 && PAIRED_VECTOR_MODE (mode))
1640 /* The CR register can only hold CC modes. */
1641 if (CR_REGNO_P (regno))
1642 return GET_MODE_CLASS (mode) == MODE_CC;
1644 if (XER_REGNO_P (regno))
1645 return mode == PSImode;
1647 /* AltiVec only in AldyVec registers. */
1648 if (ALTIVEC_REGNO_P (regno))
1649 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1651 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1652 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1655 /* We cannot put TImode anywhere except general register and it must be able
1656 to fit within the register set. In the future, allow TImode in the
1657 Altivec or VSX registers. */
1659 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1662 /* Print interesting facts about registers. */
1664 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1668 for (r = first_regno; r <= last_regno; ++r)
1670 const char *comma = "";
1673 if (first_regno == last_regno)
1674 fprintf (stderr, "%s:\t", reg_name);
1676 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1679 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1680 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1684 fprintf (stderr, ",\n\t");
1689 if (rs6000_hard_regno_nregs[m][r] > 1)
1690 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1691 rs6000_hard_regno_nregs[m][r]);
1693 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1698 if (call_used_regs[r])
1702 fprintf (stderr, ",\n\t");
1707 len += fprintf (stderr, "%s%s", comma, "call-used");
1715 fprintf (stderr, ",\n\t");
1720 len += fprintf (stderr, "%s%s", comma, "fixed");
1726 fprintf (stderr, ",\n\t");
1730 fprintf (stderr, "%sregno = %d\n", comma, r);
1734 /* Print various interesting information with -mdebug=reg. */
1736 rs6000_debug_reg_global (void)
1738 const char *nl = (const char *)0;
1740 char costly_num[20];
1742 const char *costly_str;
1743 const char *nop_str;
1745 /* Map enum rs6000_vector to string. */
1746 static const char *rs6000_debug_vector_unit[] = {
1755 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1756 LAST_VIRTUAL_REGISTER);
1757 rs6000_debug_reg_print (0, 31, "gr");
1758 rs6000_debug_reg_print (32, 63, "fp");
1759 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1762 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1763 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1764 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1765 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1766 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1767 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1768 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1769 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1770 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1774 "d reg_class = %s\n"
1775 "f reg_class = %s\n"
1776 "v reg_class = %s\n"
1777 "wa reg_class = %s\n"
1778 "wd reg_class = %s\n"
1779 "wf reg_class = %s\n"
1780 "ws reg_class = %s\n\n",
1781 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1782 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1783 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1784 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1789 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1790 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1793 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1795 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1796 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1802 switch (rs6000_sched_costly_dep)
1804 case max_dep_latency:
1805 costly_str = "max_dep_latency";
1809 costly_str = "no_dep_costly";
1812 case all_deps_costly:
1813 costly_str = "all_deps_costly";
1816 case true_store_to_load_dep_costly:
1817 costly_str = "true_store_to_load_dep_costly";
1820 case store_to_load_dep_costly:
1821 costly_str = "store_to_load_dep_costly";
1825 costly_str = costly_num;
1826 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1830 switch (rs6000_sched_insert_nops)
1832 case sched_finish_regroup_exact:
1833 nop_str = "sched_finish_regroup_exact";
1836 case sched_finish_pad_groups:
1837 nop_str = "sched_finish_pad_groups";
1840 case sched_finish_none:
1841 nop_str = "sched_finish_none";
1846 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1851 "always_hint = %s\n"
1852 "align_branch_targets = %s\n"
1853 "sched_restricted_insns_priority = %d\n"
1854 "sched_costly_dep = %s\n"
1855 "sched_insert_nops = %s\n\n",
1856 rs6000_always_hint ? "true" : "false",
1857 rs6000_align_branch_targets ? "true" : "false",
1858 (int)rs6000_sched_restricted_insns_priority,
1859 costly_str, nop_str);
1862 /* Initialize the various global tables that are based on register size. */
1864 rs6000_init_hard_regno_mode_ok (void)
1870 /* Precalculate REGNO_REG_CLASS. */
1871 rs6000_regno_regclass[0] = GENERAL_REGS;
1872 for (r = 1; r < 32; ++r)
1873 rs6000_regno_regclass[r] = BASE_REGS;
1875 for (r = 32; r < 64; ++r)
1876 rs6000_regno_regclass[r] = FLOAT_REGS;
1878 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1879 rs6000_regno_regclass[r] = NO_REGS;
1881 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1882 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1884 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1885 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1886 rs6000_regno_regclass[r] = CR_REGS;
1888 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1889 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1890 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1891 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1892 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1893 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1894 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1895 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1896 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1897 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1899 /* Precalculate vector information, this must be set up before the
1900 rs6000_hard_regno_nregs_internal below. */
1901 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1903 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1904 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1905 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1908 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1909 rs6000_constraints[c] = NO_REGS;
1911 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1912 believes it can use native alignment or still uses 128-bit alignment. */
1913 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1924 /* V2DF mode, VSX only. */
1927 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1928 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1929 rs6000_vector_align[V2DFmode] = align64;
1932 /* V4SF mode, either VSX or Altivec. */
1935 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1936 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1937 rs6000_vector_align[V4SFmode] = align32;
1939 else if (TARGET_ALTIVEC)
1941 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1942 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1943 rs6000_vector_align[V4SFmode] = align32;
1946 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1950 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1951 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1952 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1953 rs6000_vector_align[V4SImode] = align32;
1954 rs6000_vector_align[V8HImode] = align32;
1955 rs6000_vector_align[V16QImode] = align32;
1959 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1960 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1961 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1965 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1966 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1967 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1971 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1972 Altivec doesn't have 64-bit support. */
1975 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1976 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1977 rs6000_vector_align[V2DImode] = align64;
1980 /* DFmode, see if we want to use the VSX unit. */
1981 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1983 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1984 rs6000_vector_mem[DFmode]
1985 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1986 rs6000_vector_align[DFmode] = align64;
1989 /* TODO add SPE and paired floating point vector support. */
1991 /* Register class constaints for the constraints that depend on compile
1993 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1994 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1996 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1997 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2001 /* At present, we just use VSX_REGS, but we have different constraints
2002 based on the use, in case we want to fine tune the default register
2003 class used. wa = any VSX register, wf = register class to use for
2004 V4SF, wd = register class to use for V2DF, and ws = register classs to
2005 use for DF scalars. */
2006 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2007 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2008 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2009 if (TARGET_VSX_SCALAR_DOUBLE)
2010 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2014 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2016 /* Set up the reload helper functions. */
2017 if (TARGET_VSX || TARGET_ALTIVEC)
2021 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2022 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2023 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2024 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2025 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2026 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2027 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2028 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2029 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2030 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2031 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2032 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2036 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2037 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2038 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2039 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2040 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2041 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2042 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2043 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2044 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2045 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2046 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2047 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2051 /* Precalculate HARD_REGNO_NREGS. */
2052 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2053 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2054 rs6000_hard_regno_nregs[m][r]
2055 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2057 /* Precalculate HARD_REGNO_MODE_OK. */
2058 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2059 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2060 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2061 rs6000_hard_regno_mode_ok_p[m][r] = true;
2063 /* Precalculate CLASS_MAX_NREGS sizes. */
2064 for (c = 0; c < LIM_REG_CLASSES; ++c)
2068 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2069 reg_size = UNITS_PER_VSX_WORD;
2071 else if (c == ALTIVEC_REGS)
2072 reg_size = UNITS_PER_ALTIVEC_WORD;
2074 else if (c == FLOAT_REGS)
2075 reg_size = UNITS_PER_FP_WORD;
2078 reg_size = UNITS_PER_WORD;
2080 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2081 rs6000_class_max_nregs[m][c]
2082 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2085 if (TARGET_E500_DOUBLE)
2086 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2088 if (TARGET_DEBUG_REG)
2089 rs6000_debug_reg_global ();
2093 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2096 darwin_rs6000_override_options (void)
2098 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2100 rs6000_altivec_abi = 1;
2101 TARGET_ALTIVEC_VRSAVE = 1;
2102 if (DEFAULT_ABI == ABI_DARWIN)
2104 if (MACHO_DYNAMIC_NO_PIC_P)
2107 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2110 else if (flag_pic == 1)
2115 if (TARGET_64BIT && ! TARGET_POWERPC64)
2117 target_flags |= MASK_POWERPC64;
2118 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2122 rs6000_default_long_calls = 1;
2123 target_flags |= MASK_SOFT_FLOAT;
2126 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2128 if (!flag_mkernel && !flag_apple_kext
2130 && ! (target_flags_explicit & MASK_ALTIVEC))
2131 target_flags |= MASK_ALTIVEC;
2133 /* Unless the user (not the configurer) has explicitly overridden
2134 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2135 G4 unless targetting the kernel. */
2138 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2139 && ! (target_flags_explicit & MASK_ALTIVEC)
2140 && ! rs6000_select[1].string)
2142 target_flags |= MASK_ALTIVEC;
2147 /* If not otherwise specified by a target, make 'long double' equivalent to
2150 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2151 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2154 /* Override command line options. Mostly we process the processor
2155 type and sometimes adjust other TARGET_ options. */
2158 rs6000_override_options (const char *default_cpu)
2161 struct rs6000_cpu_select *ptr;
2164 /* Simplifications for entries below. */
2167 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2168 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2171 /* This table occasionally claims that a processor does not support
2172 a particular feature even though it does, but the feature is slower
2173 than the alternative. Thus, it shouldn't be relied on as a
2174 complete description of the processor's support.
2176 Please keep this list in order, and don't forget to update the
2177 documentation in invoke.texi when adding a new processor or
2181 const char *const name; /* Canonical processor name. */
2182 const enum processor_type processor; /* Processor type enum value. */
2183 const int target_enable; /* Target flags to enable. */
2184 } const processor_target_table[]
2185 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2186 {"403", PROCESSOR_PPC403,
2187 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2188 {"405", PROCESSOR_PPC405,
2189 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2190 {"405fp", PROCESSOR_PPC405,
2191 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2192 {"440", PROCESSOR_PPC440,
2193 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2194 {"440fp", PROCESSOR_PPC440,
2195 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2196 {"464", PROCESSOR_PPC440,
2197 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2198 {"464fp", PROCESSOR_PPC440,
2199 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2200 {"476", PROCESSOR_PPC476,
2201 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2202 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2203 {"476fp", PROCESSOR_PPC476,
2204 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2205 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2206 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2207 {"601", PROCESSOR_PPC601,
2208 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2209 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2210 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2211 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2212 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2213 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"620", PROCESSOR_PPC620,
2215 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2216 {"630", PROCESSOR_PPC630,
2217 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2218 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2219 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2220 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2221 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2222 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2223 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2224 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2225 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2227 /* 8548 has a dummy entry for now. */
2228 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2230 {"a2", PROCESSOR_PPCA2,
2231 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2232 | MASK_CMPB | MASK_NO_UPDATE },
2233 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2234 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2235 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2237 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2238 | MASK_PPC_GFXOPT | MASK_ISEL},
2239 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2240 {"970", PROCESSOR_POWER4,
2241 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2242 {"cell", PROCESSOR_CELL,
2243 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2244 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2245 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2246 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2247 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2248 {"G5", PROCESSOR_POWER4,
2249 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2250 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2251 {"power2", PROCESSOR_POWER,
2252 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2253 {"power3", PROCESSOR_PPC630,
2254 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2255 {"power4", PROCESSOR_POWER4,
2256 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2258 {"power5", PROCESSOR_POWER5,
2259 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2260 | MASK_MFCRF | MASK_POPCNTB},
2261 {"power5+", PROCESSOR_POWER5,
2262 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2263 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2264 {"power6", PROCESSOR_POWER6,
2265 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2266 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2267 {"power6x", PROCESSOR_POWER6,
2268 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2269 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2271 {"power7", PROCESSOR_POWER7,
2272 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2273 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2274 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2275 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2276 {"powerpc64", PROCESSOR_POWERPC64,
2277 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2278 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2279 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2280 {"rios2", PROCESSOR_RIOS2,
2281 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2282 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2283 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rs64", PROCESSOR_RS64A,
2285 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2288 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2290 /* Some OSs don't support saving the high part of 64-bit registers on
2291 context switch. Other OSs don't support saving Altivec registers.
2292 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2293 settings; if the user wants either, the user must explicitly specify
2294 them and we won't interfere with the user's specification. */
2297 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2298 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2299 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2300 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2301 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2302 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2305 /* Numerous experiment shows that IRA based loop pressure
2306 calculation works better for RTL loop invariant motion on targets
2307 with enough (>= 32) registers. It is an expensive optimization.
2308 So it is on only for peak performance. */
2310 flag_ira_loop_pressure = 1;
2312 /* Set the pointer size. */
2315 rs6000_pmode = (int)DImode;
2316 rs6000_pointer_size = 64;
2320 rs6000_pmode = (int)SImode;
2321 rs6000_pointer_size = 32;
2324 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2325 #ifdef OS_MISSING_POWERPC64
2326 if (OS_MISSING_POWERPC64)
2327 set_masks &= ~MASK_POWERPC64;
2329 #ifdef OS_MISSING_ALTIVEC
2330 if (OS_MISSING_ALTIVEC)
2331 set_masks &= ~MASK_ALTIVEC;
2334 /* Don't override by the processor default if given explicitly. */
2335 set_masks &= ~target_flags_explicit;
2337 /* Identify the processor type. */
2338 rs6000_select[0].string = default_cpu;
2339 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2341 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2343 ptr = &rs6000_select[i];
2344 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2346 for (j = 0; j < ptt_size; j++)
2347 if (! strcmp (ptr->string, processor_target_table[j].name))
2349 if (ptr->set_tune_p)
2350 rs6000_cpu = processor_target_table[j].processor;
2352 if (ptr->set_arch_p)
2354 target_flags &= ~set_masks;
2355 target_flags |= (processor_target_table[j].target_enable
2362 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2366 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2367 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2370 error ("AltiVec not supported in this target");
2372 error ("Spe not supported in this target");
2375 /* Disable Cell microcode if we are optimizing for the Cell
2376 and not optimizing for size. */
2377 if (rs6000_gen_cell_microcode == -1)
2378 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2381 /* If we are optimizing big endian systems for space, use the load/store
2382 multiple and string instructions unless we are not generating
2384 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2385 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2387 /* Don't allow -mmultiple or -mstring on little endian systems
2388 unless the cpu is a 750, because the hardware doesn't support the
2389 instructions used in little endian mode, and causes an alignment
2390 trap. The 750 does not cause an alignment trap (except when the
2391 target is unaligned). */
2393 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2395 if (TARGET_MULTIPLE)
2397 target_flags &= ~MASK_MULTIPLE;
2398 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2399 warning (0, "-mmultiple is not supported on little endian systems");
2404 target_flags &= ~MASK_STRING;
2405 if ((target_flags_explicit & MASK_STRING) != 0)
2406 warning (0, "-mstring is not supported on little endian systems");
2410 /* Add some warnings for VSX. */
2413 const char *msg = NULL;
2414 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2415 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2417 if (target_flags_explicit & MASK_VSX)
2418 msg = N_("-mvsx requires hardware floating point");
2420 target_flags &= ~ MASK_VSX;
2422 else if (TARGET_PAIRED_FLOAT)
2423 msg = N_("-mvsx and -mpaired are incompatible");
2424 /* The hardware will allow VSX and little endian, but until we make sure
2425 things like vector select, etc. work don't allow VSX on little endian
2426 systems at this point. */
2427 else if (!BYTES_BIG_ENDIAN)
2428 msg = N_("-mvsx used with little endian code");
2429 else if (TARGET_AVOID_XFORM > 0)
2430 msg = N_("-mvsx needs indexed addressing");
2431 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2433 if (target_flags_explicit & MASK_VSX)
2434 msg = N_("-mvsx and -mno-altivec are incompatible");
2436 msg = N_("-mno-altivec disables vsx");
2442 target_flags &= ~ MASK_VSX;
2444 else if (TARGET_VSX && !TARGET_ALTIVEC)
2445 target_flags |= MASK_ALTIVEC;
2448 /* Set debug flags */
2449 if (rs6000_debug_name)
2451 if (! strcmp (rs6000_debug_name, "all"))
2452 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2453 = rs6000_debug_addr = rs6000_debug_cost = 1;
2454 else if (! strcmp (rs6000_debug_name, "stack"))
2455 rs6000_debug_stack = 1;
2456 else if (! strcmp (rs6000_debug_name, "arg"))
2457 rs6000_debug_arg = 1;
2458 else if (! strcmp (rs6000_debug_name, "reg"))
2459 rs6000_debug_reg = 1;
2460 else if (! strcmp (rs6000_debug_name, "addr"))
2461 rs6000_debug_addr = 1;
2462 else if (! strcmp (rs6000_debug_name, "cost"))
2463 rs6000_debug_cost = 1;
2465 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2467 /* If the appropriate debug option is enabled, replace the target hooks
2468 with debug versions that call the real version and then prints
2469 debugging information. */
2470 if (TARGET_DEBUG_COST)
2472 targetm.rtx_costs = rs6000_debug_rtx_costs;
2473 targetm.address_cost = rs6000_debug_address_cost;
2474 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2477 if (TARGET_DEBUG_ADDR)
2479 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2480 targetm.legitimize_address = rs6000_debug_legitimize_address;
2481 rs6000_secondary_reload_class_ptr
2482 = rs6000_debug_secondary_reload_class;
2483 rs6000_secondary_memory_needed_ptr
2484 = rs6000_debug_secondary_memory_needed;
2485 rs6000_cannot_change_mode_class_ptr
2486 = rs6000_debug_cannot_change_mode_class;
2487 rs6000_preferred_reload_class_ptr
2488 = rs6000_debug_preferred_reload_class;
2489 rs6000_legitimize_reload_address_ptr
2490 = rs6000_debug_legitimize_reload_address;
2491 rs6000_mode_dependent_address_ptr
2492 = rs6000_debug_mode_dependent_address;
2496 if (rs6000_traceback_name)
2498 if (! strncmp (rs6000_traceback_name, "full", 4))
2499 rs6000_traceback = traceback_full;
2500 else if (! strncmp (rs6000_traceback_name, "part", 4))
2501 rs6000_traceback = traceback_part;
2502 else if (! strncmp (rs6000_traceback_name, "no", 2))
2503 rs6000_traceback = traceback_none;
2505 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2506 rs6000_traceback_name);
2509 if (!rs6000_explicit_options.long_double)
2510 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2512 #ifndef POWERPC_LINUX
2513 if (!rs6000_explicit_options.ieee)
2514 rs6000_ieeequad = 1;
2517 /* Enable Altivec ABI for AIX -maltivec. */
2518 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2519 rs6000_altivec_abi = 1;
2521 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2522 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2523 be explicitly overridden in either case. */
2526 if (!rs6000_explicit_options.altivec_abi
2527 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2528 rs6000_altivec_abi = 1;
2530 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2531 if (!rs6000_explicit_options.vrsave)
2532 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2535 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2536 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2538 rs6000_darwin64_abi = 1;
2540 darwin_one_byte_bool = 1;
2542 /* Default to natural alignment, for better performance. */
2543 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2546 /* Place FP constants in the constant pool instead of TOC
2547 if section anchors enabled. */
2548 if (flag_section_anchors)
2549 TARGET_NO_FP_IN_TOC = 1;
2551 /* Handle -mtls-size option. */
2552 rs6000_parse_tls_size_option ();
2554 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2555 SUBTARGET_OVERRIDE_OPTIONS;
2557 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2558 SUBSUBTARGET_OVERRIDE_OPTIONS;
2560 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2561 SUB3TARGET_OVERRIDE_OPTIONS;
2564 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2565 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2567 /* The e500 and e500mc do not have string instructions, and we set
2568 MASK_STRING above when optimizing for size. */
2569 if ((target_flags & MASK_STRING) != 0)
2570 target_flags = target_flags & ~MASK_STRING;
2572 else if (rs6000_select[1].string != NULL)
2574 /* For the powerpc-eabispe configuration, we set all these by
2575 default, so let's unset them if we manually set another
2576 CPU that is not the E500. */
2577 if (!rs6000_explicit_options.spe_abi)
2579 if (!rs6000_explicit_options.spe)
2581 if (!rs6000_explicit_options.float_gprs)
2582 rs6000_float_gprs = 0;
2583 if (!(target_flags_explicit & MASK_ISEL))
2584 target_flags &= ~MASK_ISEL;
2587 /* Detect invalid option combinations with E500. */
2590 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2591 && rs6000_cpu != PROCESSOR_POWER5
2592 && rs6000_cpu != PROCESSOR_POWER6
2593 && rs6000_cpu != PROCESSOR_POWER7
2594 && rs6000_cpu != PROCESSOR_PPCA2
2595 && rs6000_cpu != PROCESSOR_CELL);
2596 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2597 || rs6000_cpu == PROCESSOR_POWER5
2598 || rs6000_cpu == PROCESSOR_POWER7);
2599 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2600 || rs6000_cpu == PROCESSOR_POWER5
2601 || rs6000_cpu == PROCESSOR_POWER6
2602 || rs6000_cpu == PROCESSOR_POWER7
2603 || rs6000_cpu == PROCESSOR_PPCE500MC
2604 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2606 /* Allow debug switches to override the above settings. */
2607 if (TARGET_ALWAYS_HINT > 0)
2608 rs6000_always_hint = TARGET_ALWAYS_HINT;
2610 if (TARGET_SCHED_GROUPS > 0)
2611 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2613 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2614 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2616 rs6000_sched_restricted_insns_priority
2617 = (rs6000_sched_groups ? 1 : 0);
2619 /* Handle -msched-costly-dep option. */
2620 rs6000_sched_costly_dep
2621 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2623 if (rs6000_sched_costly_dep_str)
2625 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2626 rs6000_sched_costly_dep = no_dep_costly;
2627 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2628 rs6000_sched_costly_dep = all_deps_costly;
2629 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2630 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2631 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2632 rs6000_sched_costly_dep = store_to_load_dep_costly;
2634 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2635 atoi (rs6000_sched_costly_dep_str));
2638 /* Handle -minsert-sched-nops option. */
2639 rs6000_sched_insert_nops
2640 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2642 if (rs6000_sched_insert_nops_str)
2644 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2645 rs6000_sched_insert_nops = sched_finish_none;
2646 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2647 rs6000_sched_insert_nops = sched_finish_pad_groups;
2648 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2649 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2651 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2652 atoi (rs6000_sched_insert_nops_str));
2655 #ifdef TARGET_REGNAMES
2656 /* If the user desires alternate register names, copy in the
2657 alternate names now. */
2658 if (TARGET_REGNAMES)
2659 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2662 /* Set aix_struct_return last, after the ABI is determined.
2663 If -maix-struct-return or -msvr4-struct-return was explicitly
2664 used, don't override with the ABI default. */
2665 if (!rs6000_explicit_options.aix_struct_ret)
2666 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2668 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2669 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2672 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2674 /* We can only guarantee the availability of DI pseudo-ops when
2675 assembling for 64-bit targets. */
2678 targetm.asm_out.aligned_op.di = NULL;
2679 targetm.asm_out.unaligned_op.di = NULL;
2682 /* Set branch target alignment, if not optimizing for size. */
2685 /* Cell wants to be aligned 8byte for dual issue. */
2686 if (rs6000_cpu == PROCESSOR_CELL)
2688 if (align_functions <= 0)
2689 align_functions = 8;
2690 if (align_jumps <= 0)
2692 if (align_loops <= 0)
2695 if (rs6000_align_branch_targets)
2697 if (align_functions <= 0)
2698 align_functions = 16;
2699 if (align_jumps <= 0)
2701 if (align_loops <= 0)
2704 if (align_jumps_max_skip <= 0)
2705 align_jumps_max_skip = 15;
2706 if (align_loops_max_skip <= 0)
2707 align_loops_max_skip = 15;
2710 /* Arrange to save and restore machine status around nested functions. */
2711 init_machine_status = rs6000_init_machine_status;
2713 /* We should always be splitting complex arguments, but we can't break
2714 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2715 if (DEFAULT_ABI != ABI_AIX)
2716 targetm.calls.split_complex_arg = NULL;
2718 /* Initialize rs6000_cost with the appropriate target costs. */
2720 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2724 case PROCESSOR_RIOS1:
2725 rs6000_cost = &rios1_cost;
2728 case PROCESSOR_RIOS2:
2729 rs6000_cost = &rios2_cost;
2732 case PROCESSOR_RS64A:
2733 rs6000_cost = &rs64a_cost;
2736 case PROCESSOR_MPCCORE:
2737 rs6000_cost = &mpccore_cost;
2740 case PROCESSOR_PPC403:
2741 rs6000_cost = &ppc403_cost;
2744 case PROCESSOR_PPC405:
2745 rs6000_cost = &ppc405_cost;
2748 case PROCESSOR_PPC440:
2749 rs6000_cost = &ppc440_cost;
2752 case PROCESSOR_PPC476:
2753 rs6000_cost = &ppc476_cost;
2756 case PROCESSOR_PPC601:
2757 rs6000_cost = &ppc601_cost;
2760 case PROCESSOR_PPC603:
2761 rs6000_cost = &ppc603_cost;
2764 case PROCESSOR_PPC604:
2765 rs6000_cost = &ppc604_cost;
2768 case PROCESSOR_PPC604e:
2769 rs6000_cost = &ppc604e_cost;
2772 case PROCESSOR_PPC620:
2773 rs6000_cost = &ppc620_cost;
2776 case PROCESSOR_PPC630:
2777 rs6000_cost = &ppc630_cost;
2780 case PROCESSOR_CELL:
2781 rs6000_cost = &ppccell_cost;
2784 case PROCESSOR_PPC750:
2785 case PROCESSOR_PPC7400:
2786 rs6000_cost = &ppc750_cost;
2789 case PROCESSOR_PPC7450:
2790 rs6000_cost = &ppc7450_cost;
2793 case PROCESSOR_PPC8540:
2794 rs6000_cost = &ppc8540_cost;
2797 case PROCESSOR_PPCE300C2:
2798 case PROCESSOR_PPCE300C3:
2799 rs6000_cost = &ppce300c2c3_cost;
2802 case PROCESSOR_PPCE500MC:
2803 rs6000_cost = &ppce500mc_cost;
2806 case PROCESSOR_PPCE500MC64:
2807 rs6000_cost = &ppce500mc64_cost;
2810 case PROCESSOR_POWER4:
2811 case PROCESSOR_POWER5:
2812 rs6000_cost = &power4_cost;
2815 case PROCESSOR_POWER6:
2816 rs6000_cost = &power6_cost;
2819 case PROCESSOR_POWER7:
2820 rs6000_cost = &power7_cost;
2823 case PROCESSOR_PPCA2:
2824 rs6000_cost = &ppca2_cost;
2831 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2832 set_param_value ("simultaneous-prefetches",
2833 rs6000_cost->simultaneous_prefetches);
2834 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2835 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2836 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2837 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2838 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2839 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2841 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2842 can be optimized to ap = __builtin_next_arg (0). */
2843 if (DEFAULT_ABI != ABI_V4)
2844 targetm.expand_builtin_va_start = NULL;
2846 /* Set up single/double float flags.
2847 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2848 then set both flags. */
2849 if (TARGET_HARD_FLOAT && TARGET_FPRS
2850 && rs6000_single_float == 0 && rs6000_double_float == 0)
2851 rs6000_single_float = rs6000_double_float = 1;
2853 /* Reset single and double FP flags if target is E500. */
2856 rs6000_single_float = rs6000_double_float = 0;
2857 if (TARGET_E500_SINGLE)
2858 rs6000_single_float = 1;
2859 if (TARGET_E500_DOUBLE)
2860 rs6000_single_float = rs6000_double_float = 1;
2863 /* If not explicitly specified via option, decide whether to generate indexed
2864 load/store instructions. */
2865 if (TARGET_AVOID_XFORM == -1)
2866 /* Avoid indexed addressing when targeting Power6 in order to avoid
2867 the DERAT mispredict penalty. */
2868 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2870 rs6000_init_hard_regno_mode_ok ();
2873 /* Implement targetm.vectorize.builtin_mask_for_load. */
2875 rs6000_builtin_mask_for_load (void)
2877 if (TARGET_ALTIVEC || TARGET_VSX)
2878 return altivec_builtin_mask_for_load;
2883 /* Implement targetm.vectorize.builtin_conversion.
2884 Returns a decl of a function that implements conversion of an integer vector
2885 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2886 side of the conversion.
2887 Return NULL_TREE if it is not available. */
2889 rs6000_builtin_conversion (unsigned int tcode, tree type)
2891 enum tree_code code = (enum tree_code) tcode;
2895 case FIX_TRUNC_EXPR:
2896 switch (TYPE_MODE (type))
2899 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2902 return TYPE_UNSIGNED (type)
2903 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2904 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2907 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2910 return TYPE_UNSIGNED (type)
2911 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2912 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2919 switch (TYPE_MODE (type))
2922 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2925 return TYPE_UNSIGNED (type)
2926 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2927 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2930 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2933 return TYPE_UNSIGNED (type)
2934 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2935 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2946 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2948 rs6000_builtin_mul_widen_even (tree type)
2950 if (!TARGET_ALTIVEC)
2953 switch (TYPE_MODE (type))
2956 return TYPE_UNSIGNED (type)
2957 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2958 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2961 return TYPE_UNSIGNED (type)
2962 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2963 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2969 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2971 rs6000_builtin_mul_widen_odd (tree type)
2973 if (!TARGET_ALTIVEC)
2976 switch (TYPE_MODE (type))
2979 return TYPE_UNSIGNED (type)
2980 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2981 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2984 return TYPE_UNSIGNED (type)
2985 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2986 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2993 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2994 after applying N number of iterations. This routine does not determine
2995 how may iterations are required to reach desired alignment. */
2998 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3005 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3008 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3018 /* Assuming that all other types are naturally aligned. CHECKME! */
3023 /* Return true if the vector misalignment factor is supported by the
3026 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3033 /* Return if movmisalign pattern is not supported for this mode. */
3034 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3038 if (misalignment == -1)
3040 /* misalignment factor is unknown at compile time but we know
3041 it's word aligned. */
3042 if (rs6000_vector_alignment_reachable (type, is_packed))
3046 /* VSX supports word-aligned vector. */
3047 if (misalignment % 4 == 0)
3053 /* Implement targetm.vectorize.builtin_vec_perm. */
3055 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3057 tree inner_type = TREE_TYPE (type);
3058 bool uns_p = TYPE_UNSIGNED (inner_type);
3061 *mask_element_type = unsigned_char_type_node;
3063 switch (TYPE_MODE (type))
3067 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3068 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3073 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3074 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3079 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3080 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3084 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3088 if (!TARGET_ALLOW_DF_PERMUTE)
3091 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3095 if (!TARGET_ALLOW_DF_PERMUTE)
3099 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3100 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3111 /* Handle generic options of the form -mfoo=yes/no.
3112 NAME is the option name.
3113 VALUE is the option value.
3114 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3115 whether the option value is 'yes' or 'no' respectively. */
3117 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3121 else if (!strcmp (value, "yes"))
3123 else if (!strcmp (value, "no"))
3126 error ("unknown -m%s= option specified: '%s'", name, value);
3129 /* Validate and record the size specified with the -mtls-size option. */
3132 rs6000_parse_tls_size_option (void)
3134 if (rs6000_tls_size_string == 0)
3136 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3137 rs6000_tls_size = 16;
3138 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3139 rs6000_tls_size = 32;
3140 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3141 rs6000_tls_size = 64;
3143 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3147 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3149 if (DEFAULT_ABI == ABI_DARWIN)
3150 /* The Darwin libraries never set errno, so we might as well
3151 avoid calling them when that's the only reason we would. */
3152 flag_errno_math = 0;
3154 /* Double growth factor to counter reduced min jump length. */
3155 set_param_value ("max-grow-copy-bb-insns", 16);
3157 /* Enable section anchors by default.
3158 Skip section anchors for Objective C and Objective C++
3159 until front-ends fixed. */
3160 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3161 flag_section_anchors = 2;
3164 static enum fpu_type_t
3165 rs6000_parse_fpu_option (const char *option)
3167 if (!strcmp("none", option)) return FPU_NONE;
3168 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3169 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3170 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3171 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3172 error("unknown value %s for -mfpu", option);
3176 /* Returns a function decl for a vectorized version of the builtin function
3177 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3178 if it is not available. */
3181 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3184 enum machine_mode in_mode, out_mode;
3187 if (TREE_CODE (type_out) != VECTOR_TYPE
3188 || TREE_CODE (type_in) != VECTOR_TYPE
3189 || !TARGET_VECTORIZE_BUILTINS)
3192 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3193 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3194 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3195 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3199 case BUILT_IN_COPYSIGN:
3200 if (VECTOR_UNIT_VSX_P (V2DFmode)
3201 && out_mode == DFmode && out_n == 2
3202 && in_mode == DFmode && in_n == 2)
3203 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3205 case BUILT_IN_COPYSIGNF:
3206 if (out_mode != SFmode || out_n != 4
3207 || in_mode != SFmode || in_n != 4)
3209 if (VECTOR_UNIT_VSX_P (V4SFmode))
3210 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3211 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3212 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3215 if (VECTOR_UNIT_VSX_P (V2DFmode)
3216 && out_mode == DFmode && out_n == 2
3217 && in_mode == DFmode && in_n == 2)
3218 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3220 case BUILT_IN_SQRTF:
3221 if (VECTOR_UNIT_VSX_P (V4SFmode)
3222 && out_mode == SFmode && out_n == 4
3223 && in_mode == SFmode && in_n == 4)
3224 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3227 if (VECTOR_UNIT_VSX_P (V2DFmode)
3228 && out_mode == DFmode && out_n == 2
3229 && in_mode == DFmode && in_n == 2)
3230 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3232 case BUILT_IN_CEILF:
3233 if (out_mode != SFmode || out_n != 4
3234 || in_mode != SFmode || in_n != 4)
3236 if (VECTOR_UNIT_VSX_P (V4SFmode))
3237 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3238 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3239 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3241 case BUILT_IN_FLOOR:
3242 if (VECTOR_UNIT_VSX_P (V2DFmode)
3243 && out_mode == DFmode && out_n == 2
3244 && in_mode == DFmode && in_n == 2)
3245 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3247 case BUILT_IN_FLOORF:
3248 if (out_mode != SFmode || out_n != 4
3249 || in_mode != SFmode || in_n != 4)
3251 if (VECTOR_UNIT_VSX_P (V4SFmode))
3252 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3253 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3254 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3256 case BUILT_IN_TRUNC:
3257 if (VECTOR_UNIT_VSX_P (V2DFmode)
3258 && out_mode == DFmode && out_n == 2
3259 && in_mode == DFmode && in_n == 2)
3260 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3262 case BUILT_IN_TRUNCF:
3263 if (out_mode != SFmode || out_n != 4
3264 || in_mode != SFmode || in_n != 4)
3266 if (VECTOR_UNIT_VSX_P (V4SFmode))
3267 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3268 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3269 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3271 case BUILT_IN_NEARBYINT:
3272 if (VECTOR_UNIT_VSX_P (V2DFmode)
3273 && flag_unsafe_math_optimizations
3274 && out_mode == DFmode && out_n == 2
3275 && in_mode == DFmode && in_n == 2)
3276 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3278 case BUILT_IN_NEARBYINTF:
3279 if (VECTOR_UNIT_VSX_P (V4SFmode)
3280 && flag_unsafe_math_optimizations
3281 && out_mode == SFmode && out_n == 4
3282 && in_mode == SFmode && in_n == 4)
3283 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3286 if (VECTOR_UNIT_VSX_P (V2DFmode)
3287 && !flag_trapping_math
3288 && out_mode == DFmode && out_n == 2
3289 && in_mode == DFmode && in_n == 2)
3290 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3292 case BUILT_IN_RINTF:
3293 if (VECTOR_UNIT_VSX_P (V4SFmode)
3294 && !flag_trapping_math
3295 && out_mode == SFmode && out_n == 4
3296 && in_mode == SFmode && in_n == 4)
3297 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3306 /* Implement TARGET_HANDLE_OPTION. */
3309 rs6000_handle_option (size_t code, const char *arg, int value)
3311 enum fpu_type_t fpu_type = FPU_NONE;
3317 target_flags &= ~(MASK_POWER | MASK_POWER2
3318 | MASK_MULTIPLE | MASK_STRING);
3319 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3320 | MASK_MULTIPLE | MASK_STRING);
3322 case OPT_mno_powerpc:
3323 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3324 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3325 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3326 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3329 target_flags &= ~MASK_MINIMAL_TOC;
3330 TARGET_NO_FP_IN_TOC = 0;
3331 TARGET_NO_SUM_IN_TOC = 0;
3332 target_flags_explicit |= MASK_MINIMAL_TOC;
3333 #ifdef TARGET_USES_SYSV4_OPT
3334 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3335 just the same as -mminimal-toc. */
3336 target_flags |= MASK_MINIMAL_TOC;
3337 target_flags_explicit |= MASK_MINIMAL_TOC;
3341 #ifdef TARGET_USES_SYSV4_OPT
3343 /* Make -mtoc behave like -mminimal-toc. */
3344 target_flags |= MASK_MINIMAL_TOC;
3345 target_flags_explicit |= MASK_MINIMAL_TOC;
3349 #ifdef TARGET_USES_AIX64_OPT
3354 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3355 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3356 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3359 #ifdef TARGET_USES_AIX64_OPT
3364 target_flags &= ~MASK_POWERPC64;
3365 target_flags_explicit |= MASK_POWERPC64;
3368 case OPT_minsert_sched_nops_:
3369 rs6000_sched_insert_nops_str = arg;
3372 case OPT_mminimal_toc:
3375 TARGET_NO_FP_IN_TOC = 0;
3376 TARGET_NO_SUM_IN_TOC = 0;
3383 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3384 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3391 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3392 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3396 case OPT_mpowerpc_gpopt:
3397 case OPT_mpowerpc_gfxopt:
3400 target_flags |= MASK_POWERPC;
3401 target_flags_explicit |= MASK_POWERPC;
3405 case OPT_maix_struct_return:
3406 case OPT_msvr4_struct_return:
3407 rs6000_explicit_options.aix_struct_ret = true;
3411 rs6000_explicit_options.vrsave = true;
3412 TARGET_ALTIVEC_VRSAVE = value;
3416 rs6000_explicit_options.vrsave = true;
3417 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3421 target_flags_explicit |= MASK_ISEL;
3423 rs6000_parse_yes_no_option ("isel", arg, &isel);
3425 target_flags |= MASK_ISEL;
3427 target_flags &= ~MASK_ISEL;
3431 rs6000_explicit_options.spe = true;
3436 rs6000_explicit_options.spe = true;
3437 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3441 rs6000_debug_name = arg;
3444 #ifdef TARGET_USES_SYSV4_OPT
3446 rs6000_abi_name = arg;
3450 rs6000_sdata_name = arg;
3453 case OPT_mtls_size_:
3454 rs6000_tls_size_string = arg;
3457 case OPT_mrelocatable:
3460 target_flags |= MASK_MINIMAL_TOC;
3461 target_flags_explicit |= MASK_MINIMAL_TOC;
3462 TARGET_NO_FP_IN_TOC = 1;
3466 case OPT_mrelocatable_lib:
3469 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3470 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3471 TARGET_NO_FP_IN_TOC = 1;
3475 target_flags &= ~MASK_RELOCATABLE;
3476 target_flags_explicit |= MASK_RELOCATABLE;
3482 if (!strcmp (arg, "altivec"))
3484 rs6000_explicit_options.altivec_abi = true;
3485 rs6000_altivec_abi = 1;
3487 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3490 else if (! strcmp (arg, "no-altivec"))
3492 rs6000_explicit_options.altivec_abi = true;
3493 rs6000_altivec_abi = 0;
3495 else if (! strcmp (arg, "spe"))
3497 rs6000_explicit_options.spe_abi = true;
3499 rs6000_altivec_abi = 0;
3500 if (!TARGET_SPE_ABI)
3501 error ("not configured for ABI: '%s'", arg);
3503 else if (! strcmp (arg, "no-spe"))
3505 rs6000_explicit_options.spe_abi = true;
3509 /* These are here for testing during development only, do not
3510 document in the manual please. */
3511 else if (! strcmp (arg, "d64"))
3513 rs6000_darwin64_abi = 1;
3514 warning (0, "Using darwin64 ABI");
3516 else if (! strcmp (arg, "d32"))
3518 rs6000_darwin64_abi = 0;
3519 warning (0, "Using old darwin ABI");
3522 else if (! strcmp (arg, "ibmlongdouble"))
3524 rs6000_explicit_options.ieee = true;
3525 rs6000_ieeequad = 0;
3526 warning (0, "Using IBM extended precision long double");
3528 else if (! strcmp (arg, "ieeelongdouble"))
3530 rs6000_explicit_options.ieee = true;
3531 rs6000_ieeequad = 1;
3532 warning (0, "Using IEEE extended precision long double");
3537 error ("unknown ABI specified: '%s'", arg);
3543 rs6000_select[1].string = arg;
3547 rs6000_select[2].string = arg;
3550 case OPT_mtraceback_:
3551 rs6000_traceback_name = arg;
3554 case OPT_mfloat_gprs_:
3555 rs6000_explicit_options.float_gprs = true;
3556 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3557 rs6000_float_gprs = 1;
3558 else if (! strcmp (arg, "double"))
3559 rs6000_float_gprs = 2;
3560 else if (! strcmp (arg, "no"))
3561 rs6000_float_gprs = 0;
3564 error ("invalid option for -mfloat-gprs: '%s'", arg);
3569 case OPT_mlong_double_:
3570 rs6000_explicit_options.long_double = true;
3571 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3572 if (value != 64 && value != 128)
3574 error ("Unknown switch -mlong-double-%s", arg);
3575 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3579 rs6000_long_double_type_size = value;
3582 case OPT_msched_costly_dep_:
3583 rs6000_sched_costly_dep_str = arg;
3587 rs6000_explicit_options.alignment = true;
3588 if (! strcmp (arg, "power"))
3590 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3591 some C library functions, so warn about it. The flag may be
3592 useful for performance studies from time to time though, so
3593 don't disable it entirely. */
3594 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3595 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3596 " it is incompatible with the installed C and C++ libraries");
3597 rs6000_alignment_flags = MASK_ALIGN_POWER;
3599 else if (! strcmp (arg, "natural"))
3600 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3603 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3608 case OPT_msingle_float:
3609 if (!TARGET_SINGLE_FPU)
3610 warning (0, "-msingle-float option equivalent to -mhard-float");
3611 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3612 rs6000_double_float = 0;
3613 target_flags &= ~MASK_SOFT_FLOAT;
3614 target_flags_explicit |= MASK_SOFT_FLOAT;
3617 case OPT_mdouble_float:
3618 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3619 rs6000_single_float = 1;
3620 target_flags &= ~MASK_SOFT_FLOAT;
3621 target_flags_explicit |= MASK_SOFT_FLOAT;
3624 case OPT_msimple_fpu:
3625 if (!TARGET_SINGLE_FPU)
3626 warning (0, "-msimple-fpu option ignored");
3629 case OPT_mhard_float:
3630 /* -mhard_float implies -msingle-float and -mdouble-float. */
3631 rs6000_single_float = rs6000_double_float = 1;
3634 case OPT_msoft_float:
3635 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3636 rs6000_single_float = rs6000_double_float = 0;
3640 fpu_type = rs6000_parse_fpu_option(arg);
3641 if (fpu_type != FPU_NONE)
3642 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3644 target_flags &= ~MASK_SOFT_FLOAT;
3645 target_flags_explicit |= MASK_SOFT_FLOAT;
3646 rs6000_xilinx_fpu = 1;
3647 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3648 rs6000_single_float = 1;
3649 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3650 rs6000_single_float = rs6000_double_float = 1;
3651 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3652 rs6000_simple_fpu = 1;
3656 /* -mfpu=none is equivalent to -msoft-float */
3657 target_flags |= MASK_SOFT_FLOAT;
3658 target_flags_explicit |= MASK_SOFT_FLOAT;
3659 rs6000_single_float = rs6000_double_float = 0;
3666 /* Do anything needed at the start of the asm file. */
3669 rs6000_file_start (void)
3673 const char *start = buffer;
3674 struct rs6000_cpu_select *ptr;
3675 const char *default_cpu = TARGET_CPU_DEFAULT;
3676 FILE *file = asm_out_file;
3678 default_file_start ();
3680 #ifdef TARGET_BI_ARCH
3681 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3685 if (flag_verbose_asm)
3687 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3688 rs6000_select[0].string = default_cpu;
3690 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3692 ptr = &rs6000_select[i];
3693 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3695 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3700 if (PPC405_ERRATUM77)
3702 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3706 #ifdef USING_ELFOS_H
3707 switch (rs6000_sdata)
3709 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3710 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3711 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3712 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3715 if (rs6000_sdata && g_switch_value)
3717 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3727 #ifdef HAVE_AS_GNU_ATTRIBUTE
3728 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3730 fprintf (file, "\t.gnu_attribute 4, %d\n",
3731 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3732 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3734 fprintf (file, "\t.gnu_attribute 8, %d\n",
3735 (TARGET_ALTIVEC_ABI ? 2
3736 : TARGET_SPE_ABI ? 3
3738 fprintf (file, "\t.gnu_attribute 12, %d\n",
3739 aix_struct_return ? 2 : 1);
3744 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3746 switch_to_section (toc_section);
3747 switch_to_section (text_section);
3752 /* Return nonzero if this function is known to have a null epilogue. */
3755 direct_return (void)
3757 if (reload_completed)
3759 rs6000_stack_t *info = rs6000_stack_info ();
3761 if (info->first_gp_reg_save == 32
3762 && info->first_fp_reg_save == 64
3763 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3764 && ! info->lr_save_p
3765 && ! info->cr_save_p
3766 && info->vrsave_mask == 0
3774 /* Return the number of instructions it takes to form a constant in an
3775 integer register. */
3778 num_insns_constant_wide (HOST_WIDE_INT value)
3780 /* signed constant loadable with {cal|addi} */
3781 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3784 /* constant loadable with {cau|addis} */
3785 else if ((value & 0xffff) == 0
3786 && (value >> 31 == -1 || value >> 31 == 0))
3789 #if HOST_BITS_PER_WIDE_INT == 64
3790 else if (TARGET_POWERPC64)
3792 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3793 HOST_WIDE_INT high = value >> 31;
3795 if (high == 0 || high == -1)
3801 return num_insns_constant_wide (high) + 1;
3803 return num_insns_constant_wide (low) + 1;
3805 return (num_insns_constant_wide (high)
3806 + num_insns_constant_wide (low) + 1);
3815 num_insns_constant (rtx op, enum machine_mode mode)
3817 HOST_WIDE_INT low, high;
3819 switch (GET_CODE (op))
3822 #if HOST_BITS_PER_WIDE_INT == 64
3823 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3824 && mask64_operand (op, mode))
3828 return num_insns_constant_wide (INTVAL (op));
3831 if (mode == SFmode || mode == SDmode)
3836 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3837 if (DECIMAL_FLOAT_MODE_P (mode))
3838 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3840 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3841 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3844 if (mode == VOIDmode || mode == DImode)
3846 high = CONST_DOUBLE_HIGH (op);
3847 low = CONST_DOUBLE_LOW (op);
3854 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3855 if (DECIMAL_FLOAT_MODE_P (mode))
3856 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3858 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3859 high = l[WORDS_BIG_ENDIAN == 0];
3860 low = l[WORDS_BIG_ENDIAN != 0];
3864 return (num_insns_constant_wide (low)
3865 + num_insns_constant_wide (high));
3868 if ((high == 0 && low >= 0)
3869 || (high == -1 && low < 0))
3870 return num_insns_constant_wide (low);
3872 else if (mask64_operand (op, mode))
3876 return num_insns_constant_wide (high) + 1;
3879 return (num_insns_constant_wide (high)
3880 + num_insns_constant_wide (low) + 1);
3888 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3889 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3890 corresponding element of the vector, but for V4SFmode and V2SFmode,
3891 the corresponding "float" is interpreted as an SImode integer. */
3894 const_vector_elt_as_int (rtx op, unsigned int elt)
3896 rtx tmp = CONST_VECTOR_ELT (op, elt);
3897 if (GET_MODE (op) == V4SFmode
3898 || GET_MODE (op) == V2SFmode)
3899 tmp = gen_lowpart (SImode, tmp);
3900 return INTVAL (tmp);
3903 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3904 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3905 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3906 all items are set to the same value and contain COPIES replicas of the
3907 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3908 operand and the others are set to the value of the operand's msb. */
3911 vspltis_constant (rtx op, unsigned step, unsigned copies)
3913 enum machine_mode mode = GET_MODE (op);
3914 enum machine_mode inner = GET_MODE_INNER (mode);
3917 unsigned nunits = GET_MODE_NUNITS (mode);
3918 unsigned bitsize = GET_MODE_BITSIZE (inner);
3919 unsigned mask = GET_MODE_MASK (inner);
3921 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3922 HOST_WIDE_INT splat_val = val;
3923 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3925 /* Construct the value to be splatted, if possible. If not, return 0. */
3926 for (i = 2; i <= copies; i *= 2)
3928 HOST_WIDE_INT small_val;
3930 small_val = splat_val >> bitsize;
3932 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3934 splat_val = small_val;
3937 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3938 if (EASY_VECTOR_15 (splat_val))
3941 /* Also check if we can splat, and then add the result to itself. Do so if
3942 the value is positive, of if the splat instruction is using OP's mode;
3943 for splat_val < 0, the splat and the add should use the same mode. */
3944 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3945 && (splat_val >= 0 || (step == 1 && copies == 1)))
3948 /* Also check if are loading up the most significant bit which can be done by
3949 loading up -1 and shifting the value left by -1. */
3950 else if (EASY_VECTOR_MSB (splat_val, inner))
3956 /* Check if VAL is present in every STEP-th element, and the
3957 other elements are filled with its most significant bit. */
3958 for (i = 0; i < nunits - 1; ++i)
3960 HOST_WIDE_INT desired_val;
3961 if (((i + 1) & (step - 1)) == 0)
3964 desired_val = msb_val;
3966 if (desired_val != const_vector_elt_as_int (op, i))
3974 /* Return true if OP is of the given MODE and can be synthesized
3975 with a vspltisb, vspltish or vspltisw. */
3978 easy_altivec_constant (rtx op, enum machine_mode mode)
3980 unsigned step, copies;
3982 if (mode == VOIDmode)
3983 mode = GET_MODE (op);
3984 else if (mode != GET_MODE (op))
3987 /* Start with a vspltisw. */
3988 step = GET_MODE_NUNITS (mode) / 4;
3991 if (vspltis_constant (op, step, copies))
3994 /* Then try with a vspltish. */
4000 if (vspltis_constant (op, step, copies))
4003 /* And finally a vspltisb. */
4009 if (vspltis_constant (op, step, copies))
4015 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4016 result is OP. Abort if it is not possible. */
4019 gen_easy_altivec_constant (rtx op)
4021 enum machine_mode mode = GET_MODE (op);
4022 int nunits = GET_MODE_NUNITS (mode);
4023 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4024 unsigned step = nunits / 4;
4025 unsigned copies = 1;
4027 /* Start with a vspltisw. */
4028 if (vspltis_constant (op, step, copies))
4029 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4031 /* Then try with a vspltish. */
4037 if (vspltis_constant (op, step, copies))
4038 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4040 /* And finally a vspltisb. */
4046 if (vspltis_constant (op, step, copies))
4047 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4053 output_vec_const_move (rtx *operands)
4056 enum machine_mode mode;
4061 mode = GET_MODE (dest);
4063 if (TARGET_VSX && zero_constant (vec, mode))
4064 return "xxlxor %x0,%x0,%x0";
4069 if (zero_constant (vec, mode))
4070 return "vxor %0,%0,%0";
4072 splat_vec = gen_easy_altivec_constant (vec);
4073 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4074 operands[1] = XEXP (splat_vec, 0);
4075 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4078 switch (GET_MODE (splat_vec))
4081 return "vspltisw %0,%1";
4084 return "vspltish %0,%1";
4087 return "vspltisb %0,%1";
4094 gcc_assert (TARGET_SPE);
4096 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4097 pattern of V1DI, V4HI, and V2SF.
4099 FIXME: We should probably return # and add post reload
4100 splitters for these, but this way is so easy ;-). */
4101 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4102 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4103 operands[1] = CONST_VECTOR_ELT (vec, 0);
4104 operands[2] = CONST_VECTOR_ELT (vec, 1);
4106 return "li %0,%1\n\tevmergelo %0,%0,%0";
4108 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4111 /* Initialize TARGET of vector PAIRED to VALS. */
4114 paired_expand_vector_init (rtx target, rtx vals)
4116 enum machine_mode mode = GET_MODE (target);
4117 int n_elts = GET_MODE_NUNITS (mode);
4119 rtx x, new_rtx, tmp, constant_op, op1, op2;
4122 for (i = 0; i < n_elts; ++i)
4124 x = XVECEXP (vals, 0, i);
4125 if (!CONSTANT_P (x))
4130 /* Load from constant pool. */
4131 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4137 /* The vector is initialized only with non-constants. */
4138 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4139 XVECEXP (vals, 0, 1));
4141 emit_move_insn (target, new_rtx);
4145 /* One field is non-constant and the other one is a constant. Load the
4146 constant from the constant pool and use ps_merge instruction to
4147 construct the whole vector. */
4148 op1 = XVECEXP (vals, 0, 0);
4149 op2 = XVECEXP (vals, 0, 1);
4151 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4153 tmp = gen_reg_rtx (GET_MODE (constant_op));
4154 emit_move_insn (tmp, constant_op);
4156 if (CONSTANT_P (op1))
4157 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4159 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4161 emit_move_insn (target, new_rtx);
4165 paired_expand_vector_move (rtx operands[])
4167 rtx op0 = operands[0], op1 = operands[1];
4169 emit_move_insn (op0, op1);
4172 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4173 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4174 operands for the relation operation COND. This is a recursive
4178 paired_emit_vector_compare (enum rtx_code rcode,
4179 rtx dest, rtx op0, rtx op1,
4180 rtx cc_op0, rtx cc_op1)
4182 rtx tmp = gen_reg_rtx (V2SFmode);
4183 rtx tmp1, max, min, equal_zero;
4185 gcc_assert (TARGET_PAIRED_FLOAT);
4186 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4192 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4196 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4197 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4201 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4204 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4207 tmp1 = gen_reg_rtx (V2SFmode);
4208 max = gen_reg_rtx (V2SFmode);
4209 min = gen_reg_rtx (V2SFmode);
4210 equal_zero = gen_reg_rtx (V2SFmode);
4212 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4213 emit_insn (gen_selv2sf4
4214 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4215 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4216 emit_insn (gen_selv2sf4
4217 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4218 emit_insn (gen_subv2sf3 (tmp1, min, max));
4219 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4222 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4225 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4228 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4231 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4234 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4243 /* Emit vector conditional expression.
4244 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4245 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4248 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4249 rtx cond, rtx cc_op0, rtx cc_op1)
4251 enum rtx_code rcode = GET_CODE (cond);
4253 if (!TARGET_PAIRED_FLOAT)
4256 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4261 /* Initialize vector TARGET to VALS. */
4264 rs6000_expand_vector_init (rtx target, rtx vals)
4266 enum machine_mode mode = GET_MODE (target);
4267 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4268 int n_elts = GET_MODE_NUNITS (mode);
4269 int n_var = 0, one_var = -1;
4270 bool all_same = true, all_const_zero = true;
4274 for (i = 0; i < n_elts; ++i)
4276 x = XVECEXP (vals, 0, i);
4277 if (!CONSTANT_P (x))
4278 ++n_var, one_var = i;
4279 else if (x != CONST0_RTX (inner_mode))
4280 all_const_zero = false;
4282 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4288 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4289 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4290 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4292 /* Zero register. */
4293 emit_insn (gen_rtx_SET (VOIDmode, target,
4294 gen_rtx_XOR (mode, target, target)));
4297 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4299 /* Splat immediate. */
4300 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4305 /* Load from constant pool. */
4306 emit_move_insn (target, const_vec);
4311 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4312 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4316 rtx element = XVECEXP (vals, 0, 0);
4317 if (mode == V2DFmode)
4318 emit_insn (gen_vsx_splat_v2df (target, element));
4320 emit_insn (gen_vsx_splat_v2di (target, element));
4324 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4325 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4326 if (mode == V2DFmode)
4327 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4329 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4334 /* With single precision floating point on VSX, know that internally single
4335 precision is actually represented as a double, and either make 2 V2DF
4336 vectors, and convert these vectors to single precision, or do one
4337 conversion, and splat the result to the other elements. */
4338 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4342 rtx freg = gen_reg_rtx (V4SFmode);
4343 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4345 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4346 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4350 rtx dbl_even = gen_reg_rtx (V2DFmode);
4351 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4352 rtx flt_even = gen_reg_rtx (V4SFmode);
4353 rtx flt_odd = gen_reg_rtx (V4SFmode);
4355 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4356 copy_to_reg (XVECEXP (vals, 0, 0)),
4357 copy_to_reg (XVECEXP (vals, 0, 1))));
4358 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4359 copy_to_reg (XVECEXP (vals, 0, 2)),
4360 copy_to_reg (XVECEXP (vals, 0, 3))));
4361 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4362 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4363 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4368 /* Store value to stack temp. Load vector element. Splat. However, splat
4369 of 64-bit items is not supported on Altivec. */
4370 if (all_same && GET_MODE_SIZE (mode) <= 4)
4372 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4373 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4374 XVECEXP (vals, 0, 0));
4375 x = gen_rtx_UNSPEC (VOIDmode,
4376 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4377 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4379 gen_rtx_SET (VOIDmode,
4382 x = gen_rtx_VEC_SELECT (inner_mode, target,
4383 gen_rtx_PARALLEL (VOIDmode,
4384 gen_rtvec (1, const0_rtx)));
4385 emit_insn (gen_rtx_SET (VOIDmode, target,
4386 gen_rtx_VEC_DUPLICATE (mode, x)));
4390 /* One field is non-constant. Load constant then overwrite
4394 rtx copy = copy_rtx (vals);
4396 /* Load constant part of vector, substitute neighboring value for
4398 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4399 rs6000_expand_vector_init (target, copy);
4401 /* Insert variable. */
4402 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4406 /* Construct the vector in memory one field at a time
4407 and load the whole vector. */
4408 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4409 for (i = 0; i < n_elts; i++)
4410 emit_move_insn (adjust_address_nv (mem, inner_mode,
4411 i * GET_MODE_SIZE (inner_mode)),
4412 XVECEXP (vals, 0, i));
4413 emit_move_insn (target, mem);
4416 /* Set field ELT of TARGET to VAL. */
4419 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4421 enum machine_mode mode = GET_MODE (target);
4422 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4423 rtx reg = gen_reg_rtx (mode);
4425 int width = GET_MODE_SIZE (inner_mode);
4428 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4430 rtx (*set_func) (rtx, rtx, rtx, rtx)
4431 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4432 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4436 /* Load single variable value. */
4437 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4438 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4439 x = gen_rtx_UNSPEC (VOIDmode,
4440 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4441 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4443 gen_rtx_SET (VOIDmode,
4447 /* Linear sequence. */
4448 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4449 for (i = 0; i < 16; ++i)
4450 XVECEXP (mask, 0, i) = GEN_INT (i);
4452 /* Set permute mask to insert element into target. */
4453 for (i = 0; i < width; ++i)
4454 XVECEXP (mask, 0, elt*width + i)
4455 = GEN_INT (i + 0x10);
4456 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4457 x = gen_rtx_UNSPEC (mode,
4458 gen_rtvec (3, target, reg,
4459 force_reg (V16QImode, x)),
4461 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4464 /* Extract field ELT from VEC into TARGET. */
4467 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4469 enum machine_mode mode = GET_MODE (vec);
4470 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4473 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4475 rtx (*extract_func) (rtx, rtx, rtx)
4476 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4477 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4481 /* Allocate mode-sized buffer. */
4482 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4484 /* Add offset to field within buffer matching vector element. */
4485 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4487 /* Store single field into mode-sized buffer. */
4488 x = gen_rtx_UNSPEC (VOIDmode,
4489 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4490 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4492 gen_rtx_SET (VOIDmode,
4495 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4498 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4499 implement ANDing by the mask IN. */
4501 build_mask64_2_operands (rtx in, rtx *out)
4503 #if HOST_BITS_PER_WIDE_INT >= 64
4504 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4507 gcc_assert (GET_CODE (in) == CONST_INT);
4512 /* Assume c initially something like 0x00fff000000fffff. The idea
4513 is to rotate the word so that the middle ^^^^^^ group of zeros
4514 is at the MS end and can be cleared with an rldicl mask. We then
4515 rotate back and clear off the MS ^^ group of zeros with a
4517 c = ~c; /* c == 0xff000ffffff00000 */
4518 lsb = c & -c; /* lsb == 0x0000000000100000 */
4519 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4520 c = ~c; /* c == 0x00fff000000fffff */
4521 c &= -lsb; /* c == 0x00fff00000000000 */
4522 lsb = c & -c; /* lsb == 0x0000100000000000 */
4523 c = ~c; /* c == 0xff000fffffffffff */
4524 c &= -lsb; /* c == 0xff00000000000000 */
4526 while ((lsb >>= 1) != 0)
4527 shift++; /* shift == 44 on exit from loop */
4528 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4529 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4530 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4534 /* Assume c initially something like 0xff000f0000000000. The idea
4535 is to rotate the word so that the ^^^ middle group of zeros
4536 is at the LS end and can be cleared with an rldicr mask. We then
4537 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4539 lsb = c & -c; /* lsb == 0x0000010000000000 */
4540 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4541 c = ~c; /* c == 0x00fff0ffffffffff */
4542 c &= -lsb; /* c == 0x00fff00000000000 */
4543 lsb = c & -c; /* lsb == 0x0000100000000000 */
4544 c = ~c; /* c == 0xff000fffffffffff */
4545 c &= -lsb; /* c == 0xff00000000000000 */
4547 while ((lsb >>= 1) != 0)
4548 shift++; /* shift == 44 on exit from loop */
4549 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4550 m1 >>= shift; /* m1 == 0x0000000000000fff */
4551 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4554 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4555 masks will be all 1's. We are guaranteed more than one transition. */
4556 out[0] = GEN_INT (64 - shift);
4557 out[1] = GEN_INT (m1);
4558 out[2] = GEN_INT (shift);
4559 out[3] = GEN_INT (m2);
4567 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4570 invalid_e500_subreg (rtx op, enum machine_mode mode)
4572 if (TARGET_E500_DOUBLE)
4574 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4575 subreg:TI and reg:TF. Decimal float modes are like integer
4576 modes (only low part of each register used) for this
4578 if (GET_CODE (op) == SUBREG
4579 && (mode == SImode || mode == DImode || mode == TImode
4580 || mode == DDmode || mode == TDmode)
4581 && REG_P (SUBREG_REG (op))
4582 && (GET_MODE (SUBREG_REG (op)) == DFmode
4583 || GET_MODE (SUBREG_REG (op)) == TFmode))
4586 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4588 if (GET_CODE (op) == SUBREG
4589 && (mode == DFmode || mode == TFmode)
4590 && REG_P (SUBREG_REG (op))
4591 && (GET_MODE (SUBREG_REG (op)) == DImode
4592 || GET_MODE (SUBREG_REG (op)) == TImode
4593 || GET_MODE (SUBREG_REG (op)) == DDmode
4594 || GET_MODE (SUBREG_REG (op)) == TDmode))
4599 && GET_CODE (op) == SUBREG
4601 && REG_P (SUBREG_REG (op))
4602 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4608 /* AIX increases natural record alignment to doubleword if the first
4609 field is an FP double while the FP fields remain word aligned. */
4612 rs6000_special_round_type_align (tree type, unsigned int computed,
4613 unsigned int specified)
4615 unsigned int align = MAX (computed, specified);
4616 tree field = TYPE_FIELDS (type);
4618 /* Skip all non field decls */
4619 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4620 field = TREE_CHAIN (field);
4622 if (field != NULL && field != type)
4624 type = TREE_TYPE (field);
4625 while (TREE_CODE (type) == ARRAY_TYPE)
4626 type = TREE_TYPE (type);
4628 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4629 align = MAX (align, 64);
4635 /* Darwin increases record alignment to the natural alignment of
4639 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4640 unsigned int specified)
4642 unsigned int align = MAX (computed, specified);
4644 if (TYPE_PACKED (type))
4647 /* Find the first field, looking down into aggregates. */
4649 tree field = TYPE_FIELDS (type);
4650 /* Skip all non field decls */
4651 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4652 field = TREE_CHAIN (field);
4655 type = TREE_TYPE (field);
4656 while (TREE_CODE (type) == ARRAY_TYPE)
4657 type = TREE_TYPE (type);
4658 } while (AGGREGATE_TYPE_P (type));
4660 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4661 align = MAX (align, TYPE_ALIGN (type));
4666 /* Return 1 for an operand in small memory on V.4/eabi. */
4669 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4670 enum machine_mode mode ATTRIBUTE_UNUSED)
4675 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4678 if (DEFAULT_ABI != ABI_V4)
4681 /* Vector and float memory instructions have a limited offset on the
4682 SPE, so using a vector or float variable directly as an operand is
4685 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4688 if (GET_CODE (op) == SYMBOL_REF)
4691 else if (GET_CODE (op) != CONST
4692 || GET_CODE (XEXP (op, 0)) != PLUS
4693 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4694 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4699 rtx sum = XEXP (op, 0);
4700 HOST_WIDE_INT summand;
4702 /* We have to be careful here, because it is the referenced address
4703 that must be 32k from _SDA_BASE_, not just the symbol. */
4704 summand = INTVAL (XEXP (sum, 1));
4705 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4708 sym_ref = XEXP (sum, 0);
4711 return SYMBOL_REF_SMALL_P (sym_ref);
4717 /* Return true if either operand is a general purpose register. */
4720 gpr_or_gpr_p (rtx op0, rtx op1)
4722 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4723 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4727 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4730 reg_offset_addressing_ok_p (enum machine_mode mode)
4740 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4741 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4749 /* Paired vector modes. Only reg+reg addressing is valid. */
4750 if (TARGET_PAIRED_FLOAT)
4762 virtual_stack_registers_memory_p (rtx op)
4766 if (GET_CODE (op) == REG)
4767 regnum = REGNO (op);
4769 else if (GET_CODE (op) == PLUS
4770 && GET_CODE (XEXP (op, 0)) == REG
4771 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4772 regnum = REGNO (XEXP (op, 0));
4777 return (regnum >= FIRST_VIRTUAL_REGISTER
4778 && regnum <= LAST_VIRTUAL_REGISTER);
4782 constant_pool_expr_p (rtx op)
4786 split_const (op, &base, &offset);
4787 return (GET_CODE (base) == SYMBOL_REF
4788 && CONSTANT_POOL_ADDRESS_P (base)
4789 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4793 toc_relative_expr_p (rtx op)
4797 if (GET_CODE (op) != CONST)
4800 split_const (op, &base, &offset);
4801 return (GET_CODE (base) == UNSPEC
4802 && XINT (base, 1) == UNSPEC_TOCREL);
4806 legitimate_constant_pool_address_p (rtx x)
4809 && GET_CODE (x) == PLUS
4810 && GET_CODE (XEXP (x, 0)) == REG
4811 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4812 && toc_relative_expr_p (XEXP (x, 1)));
4816 legitimate_small_data_p (enum machine_mode mode, rtx x)
4818 return (DEFAULT_ABI == ABI_V4
4819 && !flag_pic && !TARGET_TOC
4820 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4821 && small_data_operand (x, mode));
4824 /* SPE offset addressing is limited to 5-bits worth of double words. */
4825 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4828 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4830 unsigned HOST_WIDE_INT offset, extra;
4832 if (GET_CODE (x) != PLUS)
4834 if (GET_CODE (XEXP (x, 0)) != REG)
4836 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4838 if (!reg_offset_addressing_ok_p (mode))
4839 return virtual_stack_registers_memory_p (x);
4840 if (legitimate_constant_pool_address_p (x))
4842 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4845 offset = INTVAL (XEXP (x, 1));
4853 /* SPE vector modes. */
4854 return SPE_CONST_OFFSET_OK (offset);
4857 if (TARGET_E500_DOUBLE)
4858 return SPE_CONST_OFFSET_OK (offset);
4860 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4862 if (VECTOR_MEM_VSX_P (DFmode))
4867 /* On e500v2, we may have:
4869 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4871 Which gets addressed with evldd instructions. */
4872 if (TARGET_E500_DOUBLE)
4873 return SPE_CONST_OFFSET_OK (offset);
4875 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4877 else if (offset & 3)
4882 if (TARGET_E500_DOUBLE)
4883 return (SPE_CONST_OFFSET_OK (offset)
4884 && SPE_CONST_OFFSET_OK (offset + 8));
4888 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4890 else if (offset & 3)
4901 return (offset < 0x10000) && (offset + extra < 0x10000);
4905 legitimate_indexed_address_p (rtx x, int strict)
4909 if (GET_CODE (x) != PLUS)
4915 /* Recognize the rtl generated by reload which we know will later be
4916 replaced with proper base and index regs. */
4918 && reload_in_progress
4919 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4923 return (REG_P (op0) && REG_P (op1)
4924 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4925 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4926 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4927 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4931 avoiding_indexed_address_p (enum machine_mode mode)
4933 /* Avoid indexed addressing for modes that have non-indexed
4934 load/store instruction forms. */
4935 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4939 legitimate_indirect_address_p (rtx x, int strict)
4941 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4945 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4947 if (!TARGET_MACHO || !flag_pic
4948 || mode != SImode || GET_CODE (x) != MEM)
4952 if (GET_CODE (x) != LO_SUM)
4954 if (GET_CODE (XEXP (x, 0)) != REG)
4956 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4960 return CONSTANT_P (x);
4964 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4966 if (GET_CODE (x) != LO_SUM)
4968 if (GET_CODE (XEXP (x, 0)) != REG)
4970 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4972 /* Restrict addressing for DI because of our SUBREG hackery. */
4973 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4974 || mode == DDmode || mode == TDmode
4979 if (TARGET_ELF || TARGET_MACHO)
4981 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4985 if (GET_MODE_NUNITS (mode) != 1)
4987 if (GET_MODE_BITSIZE (mode) > 64
4988 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4989 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4990 && (mode == DFmode || mode == DDmode))))
4993 return CONSTANT_P (x);
5000 /* Try machine-dependent ways of modifying an illegitimate address
5001 to be legitimate. If we find one, return the new, valid address.
5002 This is used from only one place: `memory_address' in explow.c.
5004 OLDX is the address as it was before break_out_memory_refs was
5005 called. In some cases it is useful to look at this to decide what
5008 It is always safe for this function to do nothing. It exists to
5009 recognize opportunities to optimize the output.
5011 On RS/6000, first check for the sum of a register with a constant
5012 integer that is out of range. If so, generate code to add the
5013 constant with the low-order 16 bits masked to the register and force
5014 this result into another register (this can be done with `cau').
5015 Then generate an address of REG+(CONST&0xffff), allowing for the
5016 possibility of bit 16 being a one.
5018 Then check for the sum of a register and something not constant, try to
5019 load the other things into a register and return the sum. */
5022 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5023 enum machine_mode mode)
5025 unsigned int extra = 0;
5027 if (!reg_offset_addressing_ok_p (mode))
5029 if (virtual_stack_registers_memory_p (x))
5032 /* In theory we should not be seeing addresses of the form reg+0,
5033 but just in case it is generated, optimize it away. */
5034 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5035 return force_reg (Pmode, XEXP (x, 0));
5037 /* Make sure both operands are registers. */
5038 else if (GET_CODE (x) == PLUS)
5039 return gen_rtx_PLUS (Pmode,
5040 force_reg (Pmode, XEXP (x, 0)),
5041 force_reg (Pmode, XEXP (x, 1)));
5043 return force_reg (Pmode, x);
5045 if (GET_CODE (x) == SYMBOL_REF)
5047 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5049 return rs6000_legitimize_tls_address (x, model);
5059 if (!TARGET_POWERPC64)
5067 extra = TARGET_POWERPC64 ? 8 : 12;
5073 if (GET_CODE (x) == PLUS
5074 && GET_CODE (XEXP (x, 0)) == REG
5075 && GET_CODE (XEXP (x, 1)) == CONST_INT
5076 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5078 && !((TARGET_POWERPC64
5079 && (mode == DImode || mode == TImode)
5080 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5081 || SPE_VECTOR_MODE (mode)
5082 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5083 || mode == DImode || mode == DDmode
5084 || mode == TDmode))))
5086 HOST_WIDE_INT high_int, low_int;
5088 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5089 if (low_int >= 0x8000 - extra)
5091 high_int = INTVAL (XEXP (x, 1)) - low_int;
5092 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5093 GEN_INT (high_int)), 0);
5094 return plus_constant (sum, low_int);
5096 else if (GET_CODE (x) == PLUS
5097 && GET_CODE (XEXP (x, 0)) == REG
5098 && GET_CODE (XEXP (x, 1)) != CONST_INT
5099 && GET_MODE_NUNITS (mode) == 1
5100 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5102 || ((mode != DImode && mode != DFmode && mode != DDmode)
5103 || (TARGET_E500_DOUBLE && mode != DDmode)))
5104 && (TARGET_POWERPC64 || mode != DImode)
5105 && !avoiding_indexed_address_p (mode)
5110 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5111 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5113 else if (SPE_VECTOR_MODE (mode)
5114 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5115 || mode == DDmode || mode == TDmode
5116 || mode == DImode)))
5120 /* We accept [reg + reg] and [reg + OFFSET]. */
5122 if (GET_CODE (x) == PLUS)
5124 rtx op1 = XEXP (x, 0);
5125 rtx op2 = XEXP (x, 1);
5128 op1 = force_reg (Pmode, op1);
5130 if (GET_CODE (op2) != REG
5131 && (GET_CODE (op2) != CONST_INT
5132 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5133 || (GET_MODE_SIZE (mode) > 8
5134 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5135 op2 = force_reg (Pmode, op2);
5137 /* We can't always do [reg + reg] for these, because [reg +
5138 reg + offset] is not a legitimate addressing mode. */
5139 y = gen_rtx_PLUS (Pmode, op1, op2);
5141 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5142 return force_reg (Pmode, y);
5147 return force_reg (Pmode, x);
5153 && GET_CODE (x) != CONST_INT
5154 && GET_CODE (x) != CONST_DOUBLE
5156 && GET_MODE_NUNITS (mode) == 1
5157 && (GET_MODE_BITSIZE (mode) <= 32
5158 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5159 && (mode == DFmode || mode == DDmode))))
5161 rtx reg = gen_reg_rtx (Pmode);
5162 emit_insn (gen_elf_high (reg, x));
5163 return gen_rtx_LO_SUM (Pmode, reg, x);
5165 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5168 && ! MACHO_DYNAMIC_NO_PIC_P
5170 && GET_CODE (x) != CONST_INT
5171 && GET_CODE (x) != CONST_DOUBLE
5173 && GET_MODE_NUNITS (mode) == 1
5174 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5175 || (mode != DFmode && mode != DDmode))
5179 rtx reg = gen_reg_rtx (Pmode);
5180 emit_insn (gen_macho_high (reg, x));
5181 return gen_rtx_LO_SUM (Pmode, reg, x);
5184 && GET_CODE (x) == SYMBOL_REF
5185 && constant_pool_expr_p (x)
5186 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5188 return create_TOC_reference (x);
5194 /* Debug version of rs6000_legitimize_address. */
5196 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5202 ret = rs6000_legitimize_address (x, oldx, mode);
5203 insns = get_insns ();
5209 "\nrs6000_legitimize_address: mode %s, old code %s, "
5210 "new code %s, modified\n",
5211 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5212 GET_RTX_NAME (GET_CODE (ret)));
5214 fprintf (stderr, "Original address:\n");
5217 fprintf (stderr, "oldx:\n");
5220 fprintf (stderr, "New address:\n");
5225 fprintf (stderr, "Insns added:\n");
5226 debug_rtx_list (insns, 20);
5232 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5233 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5244 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5245 We need to emit DTP-relative relocations. */
5248 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5253 fputs ("\t.long\t", file);
5256 fputs (DOUBLE_INT_ASM_OP, file);
5261 output_addr_const (file, x);
5262 fputs ("@dtprel+0x8000", file);
5265 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5267 static GTY(()) rtx rs6000_tls_symbol;
5269 rs6000_tls_get_addr (void)
5271 if (!rs6000_tls_symbol)
5272 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5274 return rs6000_tls_symbol;
5277 /* Construct the SYMBOL_REF for TLS GOT references. */
5279 static GTY(()) rtx rs6000_got_symbol;
5281 rs6000_got_sym (void)
5283 if (!rs6000_got_symbol)
5285 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5286 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5287 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5290 return rs6000_got_symbol;
5293 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5294 this (thread-local) address. */
5297 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5301 dest = gen_reg_rtx (Pmode);
5302 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5308 tlsreg = gen_rtx_REG (Pmode, 13);
5309 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5313 tlsreg = gen_rtx_REG (Pmode, 2);
5314 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5318 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5322 tmp = gen_reg_rtx (Pmode);
5325 tlsreg = gen_rtx_REG (Pmode, 13);
5326 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5330 tlsreg = gen_rtx_REG (Pmode, 2);
5331 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5335 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5337 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5342 rtx r3, got, tga, tmp1, tmp2, eqv;
5344 /* We currently use relocations like @got@tlsgd for tls, which
5345 means the linker will handle allocation of tls entries, placing
5346 them in the .got section. So use a pointer to the .got section,
5347 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5348 or to secondary GOT sections used by 32-bit -fPIC. */
5350 got = gen_rtx_REG (Pmode, 2);
5354 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5357 rtx gsym = rs6000_got_sym ();
5358 got = gen_reg_rtx (Pmode);
5360 rs6000_emit_move (got, gsym, Pmode);
5366 tmp1 = gen_reg_rtx (Pmode);
5367 tmp2 = gen_reg_rtx (Pmode);
5368 tmp3 = gen_reg_rtx (Pmode);
5369 mem = gen_const_mem (Pmode, tmp1);
5371 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5372 emit_move_insn (tmp1,
5373 gen_rtx_REG (Pmode, LR_REGNO));
5374 emit_move_insn (tmp2, mem);
5375 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5376 last = emit_move_insn (got, tmp3);
5377 set_unique_reg_note (last, REG_EQUAL, gsym);
5382 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5384 r3 = gen_rtx_REG (Pmode, 3);
5385 tga = rs6000_tls_get_addr ();
5387 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5388 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5389 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5390 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5391 else if (DEFAULT_ABI == ABI_V4)
5392 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5397 insn = emit_call_insn (insn);
5398 RTL_CONST_CALL_P (insn) = 1;
5399 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5400 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5401 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5402 insn = get_insns ();
5404 emit_libcall_block (insn, dest, r3, addr);
5406 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5408 r3 = gen_rtx_REG (Pmode, 3);
5409 tga = rs6000_tls_get_addr ();
5411 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5412 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5413 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5414 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5415 else if (DEFAULT_ABI == ABI_V4)
5416 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5421 insn = emit_call_insn (insn);
5422 RTL_CONST_CALL_P (insn) = 1;
5423 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5424 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5425 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5426 insn = get_insns ();
5428 tmp1 = gen_reg_rtx (Pmode);
5429 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5431 emit_libcall_block (insn, tmp1, r3, eqv);
5432 if (rs6000_tls_size == 16)
5435 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5437 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5439 else if (rs6000_tls_size == 32)
5441 tmp2 = gen_reg_rtx (Pmode);
5443 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5445 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5448 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5450 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5454 tmp2 = gen_reg_rtx (Pmode);
5456 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5458 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5460 insn = gen_rtx_SET (Pmode, dest,
5461 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5467 /* IE, or 64-bit offset LE. */
5468 tmp2 = gen_reg_rtx (Pmode);
5470 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5472 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5475 insn = gen_tls_tls_64 (dest, tmp2, addr);
5477 insn = gen_tls_tls_32 (dest, tmp2, addr);
5485 /* Return 1 if X contains a thread-local symbol. */
5488 rs6000_tls_referenced_p (rtx x)
5490 if (! TARGET_HAVE_TLS)
5493 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5496 /* Return 1 if *X is a thread-local symbol. This is the same as
5497 rs6000_tls_symbol_ref except for the type of the unused argument. */
5500 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5502 return RS6000_SYMBOL_REF_TLS_P (*x);
5505 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5506 replace the input X, or the original X if no replacement is called for.
5507 The output parameter *WIN is 1 if the calling macro should goto WIN,
5510 For RS/6000, we wish to handle large displacements off a base
5511 register by splitting the addend across an addiu/addis and the mem insn.
5512 This cuts number of extra insns needed from 3 to 1.
5514 On Darwin, we use this to generate code for floating point constants.
5515 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5516 The Darwin code is inside #if TARGET_MACHO because only then are the
5517 machopic_* functions defined. */
5519 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5520 int opnum, int type,
5521 int ind_levels ATTRIBUTE_UNUSED, int *win)
5523 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5525 /* We must recognize output that we have already generated ourselves. */
5526 if (GET_CODE (x) == PLUS
5527 && GET_CODE (XEXP (x, 0)) == PLUS
5528 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5529 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5530 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5532 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5533 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5534 opnum, (enum reload_type)type);
5540 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5541 && GET_CODE (x) == LO_SUM
5542 && GET_CODE (XEXP (x, 0)) == PLUS
5543 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5544 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5545 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5546 && machopic_operand_p (XEXP (x, 1)))
5548 /* Result of previous invocation of this function on Darwin
5549 floating point constant. */
5550 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5551 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5552 opnum, (enum reload_type)type);
5558 /* Force ld/std non-word aligned offset into base register by wrapping
5560 if (GET_CODE (x) == PLUS
5561 && GET_CODE (XEXP (x, 0)) == REG
5562 && REGNO (XEXP (x, 0)) < 32
5563 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5564 && GET_CODE (XEXP (x, 1)) == CONST_INT
5566 && (INTVAL (XEXP (x, 1)) & 3) != 0
5567 && VECTOR_MEM_NONE_P (mode)
5568 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5569 && TARGET_POWERPC64)
5571 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5572 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5573 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5574 opnum, (enum reload_type) type);
5579 if (GET_CODE (x) == PLUS
5580 && GET_CODE (XEXP (x, 0)) == REG
5581 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5582 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5583 && GET_CODE (XEXP (x, 1)) == CONST_INT
5585 && !SPE_VECTOR_MODE (mode)
5586 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5587 || mode == DDmode || mode == TDmode
5589 && VECTOR_MEM_NONE_P (mode))
5591 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5592 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5594 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5596 /* Check for 32-bit overflow. */
5597 if (high + low != val)
5603 /* Reload the high part into a base reg; leave the low part
5604 in the mem directly. */
5606 x = gen_rtx_PLUS (GET_MODE (x),
5607 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5611 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5612 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5613 opnum, (enum reload_type)type);
5618 if (GET_CODE (x) == SYMBOL_REF
5620 && VECTOR_MEM_NONE_P (mode)
5621 && !SPE_VECTOR_MODE (mode)
5623 && DEFAULT_ABI == ABI_DARWIN
5624 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5626 && DEFAULT_ABI == ABI_V4
5629 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5630 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5634 && (mode != DImode || TARGET_POWERPC64)
5635 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5636 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5641 rtx offset = machopic_gen_offset (x);
5642 x = gen_rtx_LO_SUM (GET_MODE (x),
5643 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5644 gen_rtx_HIGH (Pmode, offset)), offset);
5648 x = gen_rtx_LO_SUM (GET_MODE (x),
5649 gen_rtx_HIGH (Pmode, x), x);
5651 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5652 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5653 opnum, (enum reload_type)type);
5658 /* Reload an offset address wrapped by an AND that represents the
5659 masking of the lower bits. Strip the outer AND and let reload
5660 convert the offset address into an indirect address. For VSX,
5661 force reload to create the address with an AND in a separate
5662 register, because we can't guarantee an altivec register will
5664 if (VECTOR_MEM_ALTIVEC_P (mode)
5665 && GET_CODE (x) == AND
5666 && GET_CODE (XEXP (x, 0)) == PLUS
5667 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5668 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5669 && GET_CODE (XEXP (x, 1)) == CONST_INT
5670 && INTVAL (XEXP (x, 1)) == -16)
5679 && GET_CODE (x) == SYMBOL_REF
5680 && constant_pool_expr_p (x)
5681 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5683 x = create_TOC_reference (x);
5691 /* Debug version of rs6000_legitimize_reload_address. */
5693 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5694 int opnum, int type,
5695 int ind_levels, int *win)
5697 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5700 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5701 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5702 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5706 fprintf (stderr, "Same address returned\n");
5708 fprintf (stderr, "NULL returned\n");
5711 fprintf (stderr, "New address:\n");
5718 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5719 that is a valid memory address for an instruction.
5720 The MODE argument is the machine mode for the MEM expression
5721 that wants to use this address.
5723 On the RS/6000, there are four valid address: a SYMBOL_REF that
5724 refers to a constant pool entry of an address (or the sum of it
5725 plus a constant), a short (16-bit signed) constant plus a register,
5726 the sum of two registers, or a register indirect, possibly with an
5727 auto-increment. For DFmode, DDmode and DImode with a constant plus
5728 register, we must ensure that both words are addressable or PowerPC64
5729 with offset word aligned.
5731 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5732 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5733 because adjacent memory cells are accessed by adding word-sized offsets
5734 during assembly output. */
5736 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5738 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5740 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5741 if (VECTOR_MEM_ALTIVEC_P (mode)
5742 && GET_CODE (x) == AND
5743 && GET_CODE (XEXP (x, 1)) == CONST_INT
5744 && INTVAL (XEXP (x, 1)) == -16)
5747 if (RS6000_SYMBOL_REF_TLS_P (x))
5749 if (legitimate_indirect_address_p (x, reg_ok_strict))
5751 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5752 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5753 && !SPE_VECTOR_MODE (mode)
5756 /* Restrict addressing for DI because of our SUBREG hackery. */
5757 && !(TARGET_E500_DOUBLE
5758 && (mode == DFmode || mode == DDmode || mode == DImode))
5760 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5762 if (virtual_stack_registers_memory_p (x))
5764 if (reg_offset_p && legitimate_small_data_p (mode, x))
5766 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5768 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5771 && GET_CODE (x) == PLUS
5772 && GET_CODE (XEXP (x, 0)) == REG
5773 && (XEXP (x, 0) == virtual_stack_vars_rtx
5774 || XEXP (x, 0) == arg_pointer_rtx)
5775 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5777 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5782 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5784 || (mode != DFmode && mode != DDmode)
5785 || (TARGET_E500_DOUBLE && mode != DDmode))
5786 && (TARGET_POWERPC64 || mode != DImode)
5787 && !avoiding_indexed_address_p (mode)
5788 && legitimate_indexed_address_p (x, reg_ok_strict))
5790 if (GET_CODE (x) == PRE_MODIFY
5794 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5796 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5797 && (TARGET_POWERPC64 || mode != DImode)
5798 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5799 && !SPE_VECTOR_MODE (mode)
5800 /* Restrict addressing for DI because of our SUBREG hackery. */
5801 && !(TARGET_E500_DOUBLE
5802 && (mode == DFmode || mode == DDmode || mode == DImode))
5804 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5805 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5806 || (!avoiding_indexed_address_p (mode)
5807 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5808 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5810 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5815 /* Debug version of rs6000_legitimate_address_p. */
5817 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5820 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5822 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5823 "strict = %d, code = %s\n",
5824 ret ? "true" : "false",
5825 GET_MODE_NAME (mode),
5827 GET_RTX_NAME (GET_CODE (x)));
5833 /* Go to LABEL if ADDR (a legitimate address expression)
5834 has an effect that depends on the machine mode it is used for.
5836 On the RS/6000 this is true of all integral offsets (since AltiVec
5837 and VSX modes don't allow them) or is a pre-increment or decrement.
5839 ??? Except that due to conceptual problems in offsettable_address_p
5840 we can't really report the problems of integral offsets. So leave
5841 this assuming that the adjustable offset must be valid for the
5842 sub-words of a TFmode operand, which is what we had before. */
5845 rs6000_mode_dependent_address (rtx addr)
5847 switch (GET_CODE (addr))
5850 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5851 is considered a legitimate address before reload, so there
5852 are no offset restrictions in that case. Note that this
5853 condition is safe in strict mode because any address involving
5854 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5855 been rejected as illegitimate. */
5856 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5857 && XEXP (addr, 0) != arg_pointer_rtx
5858 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5860 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5861 return val + 12 + 0x8000 >= 0x10000;
5868 /* Auto-increment cases are now treated generically in recog.c. */
5870 return TARGET_UPDATE;
5872 /* AND is only allowed in Altivec loads. */
5883 /* Debug version of rs6000_mode_dependent_address. */
5885 rs6000_debug_mode_dependent_address (rtx addr)
5887 bool ret = rs6000_mode_dependent_address (addr);
5889 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5890 ret ? "true" : "false");
5896 /* Implement FIND_BASE_TERM. */
5899 rs6000_find_base_term (rtx op)
5903 split_const (op, &base, &offset);
5904 if (GET_CODE (base) == UNSPEC)
5905 switch (XINT (base, 1))
5908 case UNSPEC_MACHOPIC_OFFSET:
5909 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5910 for aliasing purposes. */
5911 return XVECEXP (base, 0, 0);
5917 /* More elaborate version of recog's offsettable_memref_p predicate
5918 that works around the ??? note of rs6000_mode_dependent_address.
5919 In particular it accepts
5921 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5923 in 32-bit mode, that the recog predicate rejects. */
5926 rs6000_offsettable_memref_p (rtx op)
5931 /* First mimic offsettable_memref_p. */
5932 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5935 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5936 the latter predicate knows nothing about the mode of the memory
5937 reference and, therefore, assumes that it is the largest supported
5938 mode (TFmode). As a consequence, legitimate offsettable memory
5939 references are rejected. rs6000_legitimate_offset_address_p contains
5940 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5941 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5944 /* Change register usage conditional on target flags. */
5946 rs6000_conditional_register_usage (void)
5950 /* Set MQ register fixed (already call_used) if not POWER
5951 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5956 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5958 fixed_regs[13] = call_used_regs[13]
5959 = call_really_used_regs[13] = 1;
5961 /* Conditionally disable FPRs. */
5962 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5963 for (i = 32; i < 64; i++)
5964 fixed_regs[i] = call_used_regs[i]
5965 = call_really_used_regs[i] = 1;
5967 /* The TOC register is not killed across calls in a way that is
5968 visible to the compiler. */
5969 if (DEFAULT_ABI == ABI_AIX)
5970 call_really_used_regs[2] = 0;
5972 if (DEFAULT_ABI == ABI_V4
5973 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5975 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5977 if (DEFAULT_ABI == ABI_V4
5978 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5980 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5981 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5982 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5984 if (DEFAULT_ABI == ABI_DARWIN
5985 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5986 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5987 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5988 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5990 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5991 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5992 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5996 global_regs[SPEFSCR_REGNO] = 1;
5997 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5998 registers in prologues and epilogues. We no longer use r14
5999 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6000 pool for link-compatibility with older versions of GCC. Once
6001 "old" code has died out, we can return r14 to the allocation
6004 = call_used_regs[14]
6005 = call_really_used_regs[14] = 1;
6008 if (!TARGET_ALTIVEC && !TARGET_VSX)
6010 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6011 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6012 call_really_used_regs[VRSAVE_REGNO] = 1;
6015 if (TARGET_ALTIVEC || TARGET_VSX)
6016 global_regs[VSCR_REGNO] = 1;
6018 if (TARGET_ALTIVEC_ABI)
6020 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6021 call_used_regs[i] = call_really_used_regs[i] = 1;
6023 /* AIX reserves VR20:31 in non-extended ABI mode. */
6025 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6026 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6030 /* Try to output insns to set TARGET equal to the constant C if it can
6031 be done in less than N insns. Do all computations in MODE.
6032 Returns the place where the output has been placed if it can be
6033 done and the insns have been emitted. If it would take more than N
6034 insns, zero is returned and no insns and emitted. */
6037 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6038 rtx source, int n ATTRIBUTE_UNUSED)
6040 rtx result, insn, set;
6041 HOST_WIDE_INT c0, c1;
6048 dest = gen_reg_rtx (mode);
6049 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6053 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6055 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6056 GEN_INT (INTVAL (source)
6057 & (~ (HOST_WIDE_INT) 0xffff))));
6058 emit_insn (gen_rtx_SET (VOIDmode, dest,
6059 gen_rtx_IOR (SImode, copy_rtx (result),
6060 GEN_INT (INTVAL (source) & 0xffff))));
6065 switch (GET_CODE (source))
6068 c0 = INTVAL (source);
6073 #if HOST_BITS_PER_WIDE_INT >= 64
6074 c0 = CONST_DOUBLE_LOW (source);
6077 c0 = CONST_DOUBLE_LOW (source);
6078 c1 = CONST_DOUBLE_HIGH (source);
6086 result = rs6000_emit_set_long_const (dest, c0, c1);
6093 insn = get_last_insn ();
6094 set = single_set (insn);
6095 if (! CONSTANT_P (SET_SRC (set)))
6096 set_unique_reg_note (insn, REG_EQUAL, source);
6101 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6102 fall back to a straight forward decomposition. We do this to avoid
6103 exponential run times encountered when looking for longer sequences
6104 with rs6000_emit_set_const. */
6106 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6108 if (!TARGET_POWERPC64)
6110 rtx operand1, operand2;
6112 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6114 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6116 emit_move_insn (operand1, GEN_INT (c1));
6117 emit_move_insn (operand2, GEN_INT (c2));
6121 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6124 ud2 = (c1 & 0xffff0000) >> 16;
6125 #if HOST_BITS_PER_WIDE_INT >= 64
6129 ud4 = (c2 & 0xffff0000) >> 16;
6131 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6132 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6135 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6137 emit_move_insn (dest, GEN_INT (ud1));
6140 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6141 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6144 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6147 emit_move_insn (dest, GEN_INT (ud2 << 16));
6149 emit_move_insn (copy_rtx (dest),
6150 gen_rtx_IOR (DImode, copy_rtx (dest),
6153 else if (ud3 == 0 && ud4 == 0)
6155 gcc_assert (ud2 & 0x8000);
6156 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6159 emit_move_insn (copy_rtx (dest),
6160 gen_rtx_IOR (DImode, copy_rtx (dest),
6162 emit_move_insn (copy_rtx (dest),
6163 gen_rtx_ZERO_EXTEND (DImode,
6164 gen_lowpart (SImode,
6167 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6168 || (ud4 == 0 && ! (ud3 & 0x8000)))
6171 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6174 emit_move_insn (dest, GEN_INT (ud3 << 16));
6177 emit_move_insn (copy_rtx (dest),
6178 gen_rtx_IOR (DImode, copy_rtx (dest),
6180 emit_move_insn (copy_rtx (dest),
6181 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6184 emit_move_insn (copy_rtx (dest),
6185 gen_rtx_IOR (DImode, copy_rtx (dest),
6191 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6194 emit_move_insn (dest, GEN_INT (ud4 << 16));
6197 emit_move_insn (copy_rtx (dest),
6198 gen_rtx_IOR (DImode, copy_rtx (dest),
6201 emit_move_insn (copy_rtx (dest),
6202 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6205 emit_move_insn (copy_rtx (dest),
6206 gen_rtx_IOR (DImode, copy_rtx (dest),
6207 GEN_INT (ud2 << 16)));
6209 emit_move_insn (copy_rtx (dest),
6210 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6216 /* Helper for the following. Get rid of [r+r] memory refs
6217 in cases where it won't work (TImode, TFmode, TDmode). */
6220 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6222 if (GET_CODE (operands[0]) == MEM
6223 && GET_CODE (XEXP (operands[0], 0)) != REG
6224 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6225 && ! reload_in_progress)
6227 = replace_equiv_address (operands[0],
6228 copy_addr_to_reg (XEXP (operands[0], 0)));
6230 if (GET_CODE (operands[1]) == MEM
6231 && GET_CODE (XEXP (operands[1], 0)) != REG
6232 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6233 && ! reload_in_progress)
6235 = replace_equiv_address (operands[1],
6236 copy_addr_to_reg (XEXP (operands[1], 0)));
6239 /* Emit a move from SOURCE to DEST in mode MODE. */
6241 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6245 operands[1] = source;
6247 if (TARGET_DEBUG_ADDR)
6250 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6251 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6252 GET_MODE_NAME (mode),
6255 can_create_pseudo_p ());
6257 fprintf (stderr, "source:\n");
6261 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6262 if (GET_CODE (operands[1]) == CONST_DOUBLE
6263 && ! FLOAT_MODE_P (mode)
6264 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6266 /* FIXME. This should never happen. */
6267 /* Since it seems that it does, do the safe thing and convert
6269 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6271 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6272 || FLOAT_MODE_P (mode)
6273 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6274 || CONST_DOUBLE_LOW (operands[1]) < 0)
6275 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6276 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6278 /* Check if GCC is setting up a block move that will end up using FP
6279 registers as temporaries. We must make sure this is acceptable. */
6280 if (GET_CODE (operands[0]) == MEM
6281 && GET_CODE (operands[1]) == MEM
6283 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6284 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6285 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6286 ? 32 : MEM_ALIGN (operands[0])))
6287 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6289 : MEM_ALIGN (operands[1]))))
6290 && ! MEM_VOLATILE_P (operands [0])
6291 && ! MEM_VOLATILE_P (operands [1]))
6293 emit_move_insn (adjust_address (operands[0], SImode, 0),
6294 adjust_address (operands[1], SImode, 0));
6295 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6296 adjust_address (copy_rtx (operands[1]), SImode, 4));
6300 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6301 in the secondary_reload phase, which evidently overwrites the CONST_INT
6303 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6306 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6307 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6309 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6311 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6313 if (TARGET_DEBUG_ADDR)
6315 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6319 rs6000_emit_move (tmp, add_op0, Pmode);
6320 emit_insn (gen_rtx_SET (VOIDmode, dest,
6321 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6326 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6327 && !gpc_reg_operand (operands[1], mode))
6328 operands[1] = force_reg (mode, operands[1]);
6330 if (mode == SFmode && ! TARGET_POWERPC
6331 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6332 && GET_CODE (operands[0]) == MEM)
6336 if (reload_in_progress || reload_completed)
6337 regnum = true_regnum (operands[1]);
6338 else if (GET_CODE (operands[1]) == REG)
6339 regnum = REGNO (operands[1]);
6343 /* If operands[1] is a register, on POWER it may have
6344 double-precision data in it, so truncate it to single
6346 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6349 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6350 : gen_reg_rtx (mode));
6351 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6352 operands[1] = newreg;
6356 /* Recognize the case where operand[1] is a reference to thread-local
6357 data and load its address to a register. */
6358 if (rs6000_tls_referenced_p (operands[1]))
6360 enum tls_model model;
6361 rtx tmp = operands[1];
6364 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6366 addend = XEXP (XEXP (tmp, 0), 1);
6367 tmp = XEXP (XEXP (tmp, 0), 0);
6370 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6371 model = SYMBOL_REF_TLS_MODEL (tmp);
6372 gcc_assert (model != 0);
6374 tmp = rs6000_legitimize_tls_address (tmp, model);
6377 tmp = gen_rtx_PLUS (mode, tmp, addend);
6378 tmp = force_operand (tmp, operands[0]);
6383 /* Handle the case where reload calls us with an invalid address. */
6384 if (reload_in_progress && mode == Pmode
6385 && (! general_operand (operands[1], mode)
6386 || ! nonimmediate_operand (operands[0], mode)))
6389 /* 128-bit constant floating-point values on Darwin should really be
6390 loaded as two parts. */
6391 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6392 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6394 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6395 know how to get a DFmode SUBREG of a TFmode. */
6396 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6397 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6398 simplify_gen_subreg (imode, operands[1], mode, 0),
6400 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6401 GET_MODE_SIZE (imode)),
6402 simplify_gen_subreg (imode, operands[1], mode,
6403 GET_MODE_SIZE (imode)),
6408 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6409 cfun->machine->sdmode_stack_slot =
6410 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6412 if (reload_in_progress
6414 && MEM_P (operands[0])
6415 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6416 && REG_P (operands[1]))
6418 if (FP_REGNO_P (REGNO (operands[1])))
6420 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6421 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6422 emit_insn (gen_movsd_store (mem, operands[1]));
6424 else if (INT_REGNO_P (REGNO (operands[1])))
6426 rtx mem = adjust_address_nv (operands[0], mode, 4);
6427 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6428 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6434 if (reload_in_progress
6436 && REG_P (operands[0])
6437 && MEM_P (operands[1])
6438 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6440 if (FP_REGNO_P (REGNO (operands[0])))
6442 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6443 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6444 emit_insn (gen_movsd_load (operands[0], mem));
6446 else if (INT_REGNO_P (REGNO (operands[0])))
6448 rtx mem = adjust_address_nv (operands[1], mode, 4);
6449 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6450 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6457 /* FIXME: In the long term, this switch statement should go away
6458 and be replaced by a sequence of tests based on things like
6464 if (CONSTANT_P (operands[1])
6465 && GET_CODE (operands[1]) != CONST_INT)
6466 operands[1] = force_const_mem (mode, operands[1]);
6471 rs6000_eliminate_indexed_memrefs (operands);
6478 if (CONSTANT_P (operands[1])
6479 && ! easy_fp_constant (operands[1], mode))
6480 operands[1] = force_const_mem (mode, operands[1]);
6493 if (CONSTANT_P (operands[1])
6494 && !easy_vector_constant (operands[1], mode))
6495 operands[1] = force_const_mem (mode, operands[1]);
6500 /* Use default pattern for address of ELF small data */
6503 && DEFAULT_ABI == ABI_V4
6504 && (GET_CODE (operands[1]) == SYMBOL_REF
6505 || GET_CODE (operands[1]) == CONST)
6506 && small_data_operand (operands[1], mode))
6508 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6512 if (DEFAULT_ABI == ABI_V4
6513 && mode == Pmode && mode == SImode
6514 && flag_pic == 1 && got_operand (operands[1], mode))
6516 emit_insn (gen_movsi_got (operands[0], operands[1]));
6520 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6524 && CONSTANT_P (operands[1])
6525 && GET_CODE (operands[1]) != HIGH
6526 && GET_CODE (operands[1]) != CONST_INT)
6528 rtx target = (!can_create_pseudo_p ()
6530 : gen_reg_rtx (mode));
6532 /* If this is a function address on -mcall-aixdesc,
6533 convert it to the address of the descriptor. */
6534 if (DEFAULT_ABI == ABI_AIX
6535 && GET_CODE (operands[1]) == SYMBOL_REF
6536 && XSTR (operands[1], 0)[0] == '.')
6538 const char *name = XSTR (operands[1], 0);
6540 while (*name == '.')
6542 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6543 CONSTANT_POOL_ADDRESS_P (new_ref)
6544 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6545 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6546 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6547 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6548 operands[1] = new_ref;
6551 if (DEFAULT_ABI == ABI_DARWIN)
6554 if (MACHO_DYNAMIC_NO_PIC_P)
6556 /* Take care of any required data indirection. */
6557 operands[1] = rs6000_machopic_legitimize_pic_address (
6558 operands[1], mode, operands[0]);
6559 if (operands[0] != operands[1])
6560 emit_insn (gen_rtx_SET (VOIDmode,
6561 operands[0], operands[1]));
6565 emit_insn (gen_macho_high (target, operands[1]));
6566 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6570 emit_insn (gen_elf_high (target, operands[1]));
6571 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6575 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6576 and we have put it in the TOC, we just need to make a TOC-relative
6579 && GET_CODE (operands[1]) == SYMBOL_REF
6580 && constant_pool_expr_p (operands[1])
6581 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6582 get_pool_mode (operands[1])))
6584 operands[1] = create_TOC_reference (operands[1]);
6586 else if (mode == Pmode
6587 && CONSTANT_P (operands[1])
6588 && ((GET_CODE (operands[1]) != CONST_INT
6589 && ! easy_fp_constant (operands[1], mode))
6590 || (GET_CODE (operands[1]) == CONST_INT
6591 && num_insns_constant (operands[1], mode) > 2)
6592 || (GET_CODE (operands[0]) == REG
6593 && FP_REGNO_P (REGNO (operands[0]))))
6594 && GET_CODE (operands[1]) != HIGH
6595 && ! legitimate_constant_pool_address_p (operands[1])
6596 && ! toc_relative_expr_p (operands[1]))
6600 /* Darwin uses a special PIC legitimizer. */
6601 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6604 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6606 if (operands[0] != operands[1])
6607 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6612 /* If we are to limit the number of things we put in the TOC and
6613 this is a symbol plus a constant we can add in one insn,
6614 just put the symbol in the TOC and add the constant. Don't do
6615 this if reload is in progress. */
6616 if (GET_CODE (operands[1]) == CONST
6617 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6618 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6619 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6620 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6621 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6622 && ! side_effects_p (operands[0]))
6625 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6626 rtx other = XEXP (XEXP (operands[1], 0), 1);
6628 sym = force_reg (mode, sym);
6629 emit_insn (gen_add3_insn (operands[0], sym, other));
6633 operands[1] = force_const_mem (mode, operands[1]);
6636 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6637 && constant_pool_expr_p (XEXP (operands[1], 0))
6638 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6639 get_pool_constant (XEXP (operands[1], 0)),
6640 get_pool_mode (XEXP (operands[1], 0))))
6643 = gen_const_mem (mode,
6644 create_TOC_reference (XEXP (operands[1], 0)));
6645 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6651 rs6000_eliminate_indexed_memrefs (operands);
6655 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6657 gen_rtx_SET (VOIDmode,
6658 operands[0], operands[1]),
6659 gen_rtx_CLOBBER (VOIDmode,
6660 gen_rtx_SCRATCH (SImode)))));
6666 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6669 /* Above, we may have called force_const_mem which may have returned
6670 an invalid address. If we can, fix this up; otherwise, reload will
6671 have to deal with it. */
6672 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6673 operands[1] = validize_mem (operands[1]);
6676 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6679 /* Nonzero if we can use a floating-point register to pass this arg. */
6680 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6681 (SCALAR_FLOAT_MODE_P (MODE) \
6682 && (CUM)->fregno <= FP_ARG_MAX_REG \
6683 && TARGET_HARD_FLOAT && TARGET_FPRS)
6685 /* Nonzero if we can use an AltiVec register to pass this arg. */
6686 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6687 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6688 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6689 && TARGET_ALTIVEC_ABI \
6692 /* Return a nonzero value to say to return the function value in
6693 memory, just as large structures are always returned. TYPE will be
6694 the data type of the value, and FNTYPE will be the type of the
6695 function doing the returning, or @code{NULL} for libcalls.
6697 The AIX ABI for the RS/6000 specifies that all structures are
6698 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6699 specifies that structures <= 8 bytes are returned in r3/r4, but a
6700 draft put them in memory, and GCC used to implement the draft
6701 instead of the final standard. Therefore, aix_struct_return
6702 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6703 compatibility can change DRAFT_V4_STRUCT_RET to override the
6704 default, and -m switches get the final word. See
6705 rs6000_override_options for more details.
6707 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6708 long double support is enabled. These values are returned in memory.
6710 int_size_in_bytes returns -1 for variable size objects, which go in
6711 memory always. The cast to unsigned makes -1 > 8. */
6714 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6716 /* In the darwin64 abi, try to use registers for larger structs
6718 if (rs6000_darwin64_abi
6719 && TREE_CODE (type) == RECORD_TYPE
6720 && int_size_in_bytes (type) > 0)
6722 CUMULATIVE_ARGS valcum;
6726 valcum.fregno = FP_ARG_MIN_REG;
6727 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6728 /* Do a trial code generation as if this were going to be passed
6729 as an argument; if any part goes in memory, we return NULL. */
6730 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6733 /* Otherwise fall through to more conventional ABI rules. */
6736 if (AGGREGATE_TYPE_P (type)
6737 && (aix_struct_return
6738 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6741 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6742 modes only exist for GCC vector types if -maltivec. */
6743 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6744 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6747 /* Return synthetic vectors in memory. */
6748 if (TREE_CODE (type) == VECTOR_TYPE
6749 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6751 static bool warned_for_return_big_vectors = false;
6752 if (!warned_for_return_big_vectors)
6754 warning (0, "GCC vector returned by reference: "
6755 "non-standard ABI extension with no compatibility guarantee");
6756 warned_for_return_big_vectors = true;
6761 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6767 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6768 for a call to a function whose data type is FNTYPE.
6769 For a library call, FNTYPE is 0.
6771 For incoming args we set the number of arguments in the prototype large
6772 so we never return a PARALLEL. */
6775 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6776 rtx libname ATTRIBUTE_UNUSED, int incoming,
6777 int libcall, int n_named_args)
6779 static CUMULATIVE_ARGS zero_cumulative;
6781 *cum = zero_cumulative;
6783 cum->fregno = FP_ARG_MIN_REG;
6784 cum->vregno = ALTIVEC_ARG_MIN_REG;
6785 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6786 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6787 ? CALL_LIBCALL : CALL_NORMAL);
6788 cum->sysv_gregno = GP_ARG_MIN_REG;
6789 cum->stdarg = fntype
6790 && (TYPE_ARG_TYPES (fntype) != 0
6791 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6792 != void_type_node));
6794 cum->nargs_prototype = 0;
6795 if (incoming || cum->prototype)
6796 cum->nargs_prototype = n_named_args;
6798 /* Check for a longcall attribute. */
6799 if ((!fntype && rs6000_default_long_calls)
6801 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6802 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6803 cum->call_cookie |= CALL_LONG;
6805 if (TARGET_DEBUG_ARG)
6807 fprintf (stderr, "\ninit_cumulative_args:");
6810 tree ret_type = TREE_TYPE (fntype);
6811 fprintf (stderr, " ret code = %s,",
6812 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6815 if (cum->call_cookie & CALL_LONG)
6816 fprintf (stderr, " longcall,");
6818 fprintf (stderr, " proto = %d, nargs = %d\n",
6819 cum->prototype, cum->nargs_prototype);
6824 && TARGET_ALTIVEC_ABI
6825 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6827 error ("cannot return value in vector register because"
6828 " altivec instructions are disabled, use -maltivec"
6833 /* Return true if TYPE must be passed on the stack and not in registers. */
6836 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6838 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6839 return must_pass_in_stack_var_size (mode, type);
6841 return must_pass_in_stack_var_size_or_pad (mode, type);
6844 /* If defined, a C expression which determines whether, and in which
6845 direction, to pad out an argument with extra space. The value
6846 should be of type `enum direction': either `upward' to pad above
6847 the argument, `downward' to pad below, or `none' to inhibit
6850 For the AIX ABI structs are always stored left shifted in their
6854 function_arg_padding (enum machine_mode mode, const_tree type)
6856 #ifndef AGGREGATE_PADDING_FIXED
6857 #define AGGREGATE_PADDING_FIXED 0
6859 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6860 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6863 if (!AGGREGATE_PADDING_FIXED)
6865 /* GCC used to pass structures of the same size as integer types as
6866 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6867 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6868 passed padded downward, except that -mstrict-align further
6869 muddied the water in that multi-component structures of 2 and 4
6870 bytes in size were passed padded upward.
6872 The following arranges for best compatibility with previous
6873 versions of gcc, but removes the -mstrict-align dependency. */
6874 if (BYTES_BIG_ENDIAN)
6876 HOST_WIDE_INT size = 0;
6878 if (mode == BLKmode)
6880 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6881 size = int_size_in_bytes (type);
6884 size = GET_MODE_SIZE (mode);
6886 if (size == 1 || size == 2 || size == 4)
6892 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6894 if (type != 0 && AGGREGATE_TYPE_P (type))
6898 /* Fall back to the default. */
6899 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6902 /* If defined, a C expression that gives the alignment boundary, in bits,
6903 of an argument with the specified mode and type. If it is not defined,
6904 PARM_BOUNDARY is used for all arguments.
6906 V.4 wants long longs and doubles to be double word aligned. Just
6907 testing the mode size is a boneheaded way to do this as it means
6908 that other types such as complex int are also double word aligned.
6909 However, we're stuck with this because changing the ABI might break
6910 existing library interfaces.
6912 Doubleword align SPE vectors.
6913 Quadword align Altivec vectors.
6914 Quadword align large synthetic vector types. */
6917 function_arg_boundary (enum machine_mode mode, tree type)
6919 if (DEFAULT_ABI == ABI_V4
6920 && (GET_MODE_SIZE (mode) == 8
6921 || (TARGET_HARD_FLOAT
6923 && (mode == TFmode || mode == TDmode))))
6925 else if (SPE_VECTOR_MODE (mode)
6926 || (type && TREE_CODE (type) == VECTOR_TYPE
6927 && int_size_in_bytes (type) >= 8
6928 && int_size_in_bytes (type) < 16))
6930 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6931 || (type && TREE_CODE (type) == VECTOR_TYPE
6932 && int_size_in_bytes (type) >= 16))
6934 else if (rs6000_darwin64_abi && mode == BLKmode
6935 && type && TYPE_ALIGN (type) > 64)
6938 return PARM_BOUNDARY;
6941 /* For a function parm of MODE and TYPE, return the starting word in
6942 the parameter area. NWORDS of the parameter area are already used. */
6945 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6948 unsigned int parm_offset;
6950 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6951 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6952 return nwords + (-(parm_offset + nwords) & align);
6955 /* Compute the size (in words) of a function argument. */
6957 static unsigned long
6958 rs6000_arg_size (enum machine_mode mode, tree type)
6962 if (mode != BLKmode)
6963 size = GET_MODE_SIZE (mode);
6965 size = int_size_in_bytes (type);
6968 return (size + 3) >> 2;
6970 return (size + 7) >> 3;
6973 /* Use this to flush pending int fields. */
6976 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6977 HOST_WIDE_INT bitpos)
6979 unsigned int startbit, endbit;
6980 int intregs, intoffset;
6981 enum machine_mode mode;
6983 if (cum->intoffset == -1)
6986 intoffset = cum->intoffset;
6987 cum->intoffset = -1;
6989 if (intoffset % BITS_PER_WORD != 0)
6991 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6993 if (mode == BLKmode)
6995 /* We couldn't find an appropriate mode, which happens,
6996 e.g., in packed structs when there are 3 bytes to load.
6997 Back intoffset back to the beginning of the word in this
6999 intoffset = intoffset & -BITS_PER_WORD;
7003 startbit = intoffset & -BITS_PER_WORD;
7004 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7005 intregs = (endbit - startbit) / BITS_PER_WORD;
7006 cum->words += intregs;
7009 /* The darwin64 ABI calls for us to recurse down through structs,
7010 looking for elements passed in registers. Unfortunately, we have
7011 to track int register count here also because of misalignments
7012 in powerpc alignment mode. */
7015 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7017 HOST_WIDE_INT startbitpos)
7021 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7022 if (TREE_CODE (f) == FIELD_DECL)
7024 HOST_WIDE_INT bitpos = startbitpos;
7025 tree ftype = TREE_TYPE (f);
7026 enum machine_mode mode;
7027 if (ftype == error_mark_node)
7029 mode = TYPE_MODE (ftype);
7031 if (DECL_SIZE (f) != 0
7032 && host_integerp (bit_position (f), 1))
7033 bitpos += int_bit_position (f);
7035 /* ??? FIXME: else assume zero offset. */
7037 if (TREE_CODE (ftype) == RECORD_TYPE)
7038 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7039 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7041 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7042 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7043 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7045 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7047 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7051 else if (cum->intoffset == -1)
7052 cum->intoffset = bitpos;
7056 /* Update the data in CUM to advance over an argument
7057 of mode MODE and data type TYPE.
7058 (TYPE is null for libcalls where that information may not be available.)
7060 Note that for args passed by reference, function_arg will be called
7061 with MODE and TYPE set to that of the pointer to the arg, not the arg
7065 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7066 tree type, int named, int depth)
7070 /* Only tick off an argument if we're not recursing. */
7072 cum->nargs_prototype--;
7074 if (TARGET_ALTIVEC_ABI
7075 && (ALTIVEC_VECTOR_MODE (mode)
7076 || VSX_VECTOR_MODE (mode)
7077 || (type && TREE_CODE (type) == VECTOR_TYPE
7078 && int_size_in_bytes (type) == 16)))
7082 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7085 if (!TARGET_ALTIVEC)
7086 error ("cannot pass argument in vector register because"
7087 " altivec instructions are disabled, use -maltivec"
7090 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7091 even if it is going to be passed in a vector register.
7092 Darwin does the same for variable-argument functions. */
7093 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7094 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7104 /* Vector parameters must be 16-byte aligned. This places
7105 them at 2 mod 4 in terms of words in 32-bit mode, since
7106 the parameter save area starts at offset 24 from the
7107 stack. In 64-bit mode, they just have to start on an
7108 even word, since the parameter save area is 16-byte
7109 aligned. Space for GPRs is reserved even if the argument
7110 will be passed in memory. */
7112 align = (2 - cum->words) & 3;
7114 align = cum->words & 1;
7115 cum->words += align + rs6000_arg_size (mode, type);
7117 if (TARGET_DEBUG_ARG)
7119 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7121 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7122 cum->nargs_prototype, cum->prototype,
7123 GET_MODE_NAME (mode));
7127 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7129 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7132 else if (rs6000_darwin64_abi
7134 && TREE_CODE (type) == RECORD_TYPE
7135 && (size = int_size_in_bytes (type)) > 0)
7137 /* Variable sized types have size == -1 and are
7138 treated as if consisting entirely of ints.
7139 Pad to 16 byte boundary if needed. */
7140 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7141 && (cum->words % 2) != 0)
7143 /* For varargs, we can just go up by the size of the struct. */
7145 cum->words += (size + 7) / 8;
7148 /* It is tempting to say int register count just goes up by
7149 sizeof(type)/8, but this is wrong in a case such as
7150 { int; double; int; } [powerpc alignment]. We have to
7151 grovel through the fields for these too. */
7153 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7154 rs6000_darwin64_record_arg_advance_flush (cum,
7155 size * BITS_PER_UNIT);
7158 else if (DEFAULT_ABI == ABI_V4)
7160 if (TARGET_HARD_FLOAT && TARGET_FPRS
7161 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7162 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7163 || (mode == TFmode && !TARGET_IEEEQUAD)
7164 || mode == SDmode || mode == DDmode || mode == TDmode))
7166 /* _Decimal128 must use an even/odd register pair. This assumes
7167 that the register number is odd when fregno is odd. */
7168 if (mode == TDmode && (cum->fregno % 2) == 1)
7171 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7172 <= FP_ARG_V4_MAX_REG)
7173 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7176 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7177 if (mode == DFmode || mode == TFmode
7178 || mode == DDmode || mode == TDmode)
7179 cum->words += cum->words & 1;
7180 cum->words += rs6000_arg_size (mode, type);
7185 int n_words = rs6000_arg_size (mode, type);
7186 int gregno = cum->sysv_gregno;
7188 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7189 (r7,r8) or (r9,r10). As does any other 2 word item such
7190 as complex int due to a historical mistake. */
7192 gregno += (1 - gregno) & 1;
7194 /* Multi-reg args are not split between registers and stack. */
7195 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7197 /* Long long and SPE vectors are aligned on the stack.
7198 So are other 2 word items such as complex int due to
7199 a historical mistake. */
7201 cum->words += cum->words & 1;
7202 cum->words += n_words;
7205 /* Note: continuing to accumulate gregno past when we've started
7206 spilling to the stack indicates the fact that we've started
7207 spilling to the stack to expand_builtin_saveregs. */
7208 cum->sysv_gregno = gregno + n_words;
7211 if (TARGET_DEBUG_ARG)
7213 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7214 cum->words, cum->fregno);
7215 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7216 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7217 fprintf (stderr, "mode = %4s, named = %d\n",
7218 GET_MODE_NAME (mode), named);
7223 int n_words = rs6000_arg_size (mode, type);
7224 int start_words = cum->words;
7225 int align_words = rs6000_parm_start (mode, type, start_words);
7227 cum->words = align_words + n_words;
7229 if (SCALAR_FLOAT_MODE_P (mode)
7230 && TARGET_HARD_FLOAT && TARGET_FPRS)
7232 /* _Decimal128 must be passed in an even/odd float register pair.
7233 This assumes that the register number is odd when fregno is
7235 if (mode == TDmode && (cum->fregno % 2) == 1)
7237 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7240 if (TARGET_DEBUG_ARG)
7242 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7243 cum->words, cum->fregno);
7244 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7245 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7246 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7247 named, align_words - start_words, depth);
7253 spe_build_register_parallel (enum machine_mode mode, int gregno)
7260 r1 = gen_rtx_REG (DImode, gregno);
7261 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7262 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7266 r1 = gen_rtx_REG (DImode, gregno);
7267 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7268 r3 = gen_rtx_REG (DImode, gregno + 2);
7269 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7270 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7273 r1 = gen_rtx_REG (DImode, gregno);
7274 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7275 r3 = gen_rtx_REG (DImode, gregno + 2);
7276 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7277 r5 = gen_rtx_REG (DImode, gregno + 4);
7278 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7279 r7 = gen_rtx_REG (DImode, gregno + 6);
7280 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7281 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7288 /* Determine where to put a SIMD argument on the SPE. */
7290 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7293 int gregno = cum->sysv_gregno;
7295 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7296 are passed and returned in a pair of GPRs for ABI compatibility. */
7297 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7298 || mode == DCmode || mode == TCmode))
7300 int n_words = rs6000_arg_size (mode, type);
7302 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7304 gregno += (1 - gregno) & 1;
7306 /* Multi-reg args are not split between registers and stack. */
7307 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7310 return spe_build_register_parallel (mode, gregno);
7314 int n_words = rs6000_arg_size (mode, type);
7316 /* SPE vectors are put in odd registers. */
7317 if (n_words == 2 && (gregno & 1) == 0)
7320 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7323 enum machine_mode m = SImode;
7325 r1 = gen_rtx_REG (m, gregno);
7326 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7327 r2 = gen_rtx_REG (m, gregno + 1);
7328 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7329 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7336 if (gregno <= GP_ARG_MAX_REG)
7337 return gen_rtx_REG (mode, gregno);
7343 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7344 structure between cum->intoffset and bitpos to integer registers. */
7347 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7348 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7350 enum machine_mode mode;
7352 unsigned int startbit, endbit;
7353 int this_regno, intregs, intoffset;
7356 if (cum->intoffset == -1)
7359 intoffset = cum->intoffset;
7360 cum->intoffset = -1;
7362 /* If this is the trailing part of a word, try to only load that
7363 much into the register. Otherwise load the whole register. Note
7364 that in the latter case we may pick up unwanted bits. It's not a
7365 problem at the moment but may wish to revisit. */
7367 if (intoffset % BITS_PER_WORD != 0)
7369 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7371 if (mode == BLKmode)
7373 /* We couldn't find an appropriate mode, which happens,
7374 e.g., in packed structs when there are 3 bytes to load.
7375 Back intoffset back to the beginning of the word in this
7377 intoffset = intoffset & -BITS_PER_WORD;
7384 startbit = intoffset & -BITS_PER_WORD;
7385 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7386 intregs = (endbit - startbit) / BITS_PER_WORD;
7387 this_regno = cum->words + intoffset / BITS_PER_WORD;
7389 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7392 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7396 intoffset /= BITS_PER_UNIT;
7399 regno = GP_ARG_MIN_REG + this_regno;
7400 reg = gen_rtx_REG (mode, regno);
7402 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7405 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7409 while (intregs > 0);
7412 /* Recursive workhorse for the following. */
7415 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7416 HOST_WIDE_INT startbitpos, rtx rvec[],
7421 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7422 if (TREE_CODE (f) == FIELD_DECL)
7424 HOST_WIDE_INT bitpos = startbitpos;
7425 tree ftype = TREE_TYPE (f);
7426 enum machine_mode mode;
7427 if (ftype == error_mark_node)
7429 mode = TYPE_MODE (ftype);
7431 if (DECL_SIZE (f) != 0
7432 && host_integerp (bit_position (f), 1))
7433 bitpos += int_bit_position (f);
7435 /* ??? FIXME: else assume zero offset. */
7437 if (TREE_CODE (ftype) == RECORD_TYPE)
7438 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7439 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7444 case SCmode: mode = SFmode; break;
7445 case DCmode: mode = DFmode; break;
7446 case TCmode: mode = TFmode; break;
7450 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7452 = gen_rtx_EXPR_LIST (VOIDmode,
7453 gen_rtx_REG (mode, cum->fregno++),
7454 GEN_INT (bitpos / BITS_PER_UNIT));
7455 if (mode == TFmode || mode == TDmode)
7458 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7460 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7462 = gen_rtx_EXPR_LIST (VOIDmode,
7463 gen_rtx_REG (mode, cum->vregno++),
7464 GEN_INT (bitpos / BITS_PER_UNIT));
7466 else if (cum->intoffset == -1)
7467 cum->intoffset = bitpos;
7471 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7472 the register(s) to be used for each field and subfield of a struct
7473 being passed by value, along with the offset of where the
7474 register's value may be found in the block. FP fields go in FP
7475 register, vector fields go in vector registers, and everything
7476 else goes in int registers, packed as in memory.
7478 This code is also used for function return values. RETVAL indicates
7479 whether this is the case.
7481 Much of this is taken from the SPARC V9 port, which has a similar
7482 calling convention. */
7485 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7486 int named, bool retval)
7488 rtx rvec[FIRST_PSEUDO_REGISTER];
7489 int k = 1, kbase = 1;
7490 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7491 /* This is a copy; modifications are not visible to our caller. */
7492 CUMULATIVE_ARGS copy_cum = *orig_cum;
7493 CUMULATIVE_ARGS *cum = ©_cum;
7495 /* Pad to 16 byte boundary if needed. */
7496 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7497 && (cum->words % 2) != 0)
7504 /* Put entries into rvec[] for individual FP and vector fields, and
7505 for the chunks of memory that go in int regs. Note we start at
7506 element 1; 0 is reserved for an indication of using memory, and
7507 may or may not be filled in below. */
7508 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7509 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7511 /* If any part of the struct went on the stack put all of it there.
7512 This hack is because the generic code for
7513 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7514 parts of the struct are not at the beginning. */
7518 return NULL_RTX; /* doesn't go in registers at all */
7520 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7522 if (k > 1 || cum->use_stack)
7523 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7528 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7531 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7535 rtx rvec[GP_ARG_NUM_REG + 1];
7537 if (align_words >= GP_ARG_NUM_REG)
7540 n_units = rs6000_arg_size (mode, type);
7542 /* Optimize the simple case where the arg fits in one gpr, except in
7543 the case of BLKmode due to assign_parms assuming that registers are
7544 BITS_PER_WORD wide. */
7546 || (n_units == 1 && mode != BLKmode))
7547 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7550 if (align_words + n_units > GP_ARG_NUM_REG)
7551 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7552 using a magic NULL_RTX component.
7553 This is not strictly correct. Only some of the arg belongs in
7554 memory, not all of it. However, the normal scheme using
7555 function_arg_partial_nregs can result in unusual subregs, eg.
7556 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7557 store the whole arg to memory is often more efficient than code
7558 to store pieces, and we know that space is available in the right
7559 place for the whole arg. */
7560 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7565 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7566 rtx off = GEN_INT (i++ * 4);
7567 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7569 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7571 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7574 /* Determine where to put an argument to a function.
7575 Value is zero to push the argument on the stack,
7576 or a hard register in which to store the argument.
7578 MODE is the argument's machine mode.
7579 TYPE is the data type of the argument (as a tree).
7580 This is null for libcalls where that information may
7582 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7583 the preceding args and about the function being called. It is
7584 not modified in this routine.
7585 NAMED is nonzero if this argument is a named parameter
7586 (otherwise it is an extra parameter matching an ellipsis).
7588 On RS/6000 the first eight words of non-FP are normally in registers
7589 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7590 Under V.4, the first 8 FP args are in registers.
7592 If this is floating-point and no prototype is specified, we use
7593 both an FP and integer register (or possibly FP reg and stack). Library
7594 functions (when CALL_LIBCALL is set) always have the proper types for args,
7595 so we can pass the FP value just in one register. emit_library_function
7596 doesn't support PARALLEL anyway.
7598 Note that for args passed by reference, function_arg will be called
7599 with MODE and TYPE set to that of the pointer to the arg, not the arg
7603 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7604 tree type, int named)
7606 enum rs6000_abi abi = DEFAULT_ABI;
7608 /* Return a marker to indicate whether CR1 needs to set or clear the
7609 bit that V.4 uses to say fp args were passed in registers.
7610 Assume that we don't need the marker for software floating point,
7611 or compiler generated library calls. */
7612 if (mode == VOIDmode)
7615 && (cum->call_cookie & CALL_LIBCALL) == 0
7617 || (cum->nargs_prototype < 0
7618 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7620 /* For the SPE, we need to crxor CR6 always. */
7622 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7623 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7624 return GEN_INT (cum->call_cookie
7625 | ((cum->fregno == FP_ARG_MIN_REG)
7626 ? CALL_V4_SET_FP_ARGS
7627 : CALL_V4_CLEAR_FP_ARGS));
7630 return GEN_INT (cum->call_cookie);
7633 if (rs6000_darwin64_abi && mode == BLKmode
7634 && TREE_CODE (type) == RECORD_TYPE)
7636 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7637 if (rslt != NULL_RTX)
7639 /* Else fall through to usual handling. */
7642 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7643 if (TARGET_64BIT && ! cum->prototype)
7645 /* Vector parameters get passed in vector register
7646 and also in GPRs or memory, in absence of prototype. */
7649 align_words = (cum->words + 1) & ~1;
7651 if (align_words >= GP_ARG_NUM_REG)
7657 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7659 return gen_rtx_PARALLEL (mode,
7661 gen_rtx_EXPR_LIST (VOIDmode,
7663 gen_rtx_EXPR_LIST (VOIDmode,
7664 gen_rtx_REG (mode, cum->vregno),
7668 return gen_rtx_REG (mode, cum->vregno);
7669 else if (TARGET_ALTIVEC_ABI
7670 && (ALTIVEC_VECTOR_MODE (mode)
7671 || VSX_VECTOR_MODE (mode)
7672 || (type && TREE_CODE (type) == VECTOR_TYPE
7673 && int_size_in_bytes (type) == 16)))
7675 if (named || abi == ABI_V4)
7679 /* Vector parameters to varargs functions under AIX or Darwin
7680 get passed in memory and possibly also in GPRs. */
7681 int align, align_words, n_words;
7682 enum machine_mode part_mode;
7684 /* Vector parameters must be 16-byte aligned. This places them at
7685 2 mod 4 in terms of words in 32-bit mode, since the parameter
7686 save area starts at offset 24 from the stack. In 64-bit mode,
7687 they just have to start on an even word, since the parameter
7688 save area is 16-byte aligned. */
7690 align = (2 - cum->words) & 3;
7692 align = cum->words & 1;
7693 align_words = cum->words + align;
7695 /* Out of registers? Memory, then. */
7696 if (align_words >= GP_ARG_NUM_REG)
7699 if (TARGET_32BIT && TARGET_POWERPC64)
7700 return rs6000_mixed_function_arg (mode, type, align_words);
7702 /* The vector value goes in GPRs. Only the part of the
7703 value in GPRs is reported here. */
7705 n_words = rs6000_arg_size (mode, type);
7706 if (align_words + n_words > GP_ARG_NUM_REG)
7707 /* Fortunately, there are only two possibilities, the value
7708 is either wholly in GPRs or half in GPRs and half not. */
7711 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7714 else if (TARGET_SPE_ABI && TARGET_SPE
7715 && (SPE_VECTOR_MODE (mode)
7716 || (TARGET_E500_DOUBLE && (mode == DFmode
7719 || mode == TCmode))))
7720 return rs6000_spe_function_arg (cum, mode, type);
7722 else if (abi == ABI_V4)
7724 if (TARGET_HARD_FLOAT && TARGET_FPRS
7725 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7726 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7727 || (mode == TFmode && !TARGET_IEEEQUAD)
7728 || mode == SDmode || mode == DDmode || mode == TDmode))
7730 /* _Decimal128 must use an even/odd register pair. This assumes
7731 that the register number is odd when fregno is odd. */
7732 if (mode == TDmode && (cum->fregno % 2) == 1)
7735 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7736 <= FP_ARG_V4_MAX_REG)
7737 return gen_rtx_REG (mode, cum->fregno);
7743 int n_words = rs6000_arg_size (mode, type);
7744 int gregno = cum->sysv_gregno;
7746 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7747 (r7,r8) or (r9,r10). As does any other 2 word item such
7748 as complex int due to a historical mistake. */
7750 gregno += (1 - gregno) & 1;
7752 /* Multi-reg args are not split between registers and stack. */
7753 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7756 if (TARGET_32BIT && TARGET_POWERPC64)
7757 return rs6000_mixed_function_arg (mode, type,
7758 gregno - GP_ARG_MIN_REG);
7759 return gen_rtx_REG (mode, gregno);
7764 int align_words = rs6000_parm_start (mode, type, cum->words);
7766 /* _Decimal128 must be passed in an even/odd float register pair.
7767 This assumes that the register number is odd when fregno is odd. */
7768 if (mode == TDmode && (cum->fregno % 2) == 1)
7771 if (USE_FP_FOR_ARG_P (cum, mode, type))
7773 rtx rvec[GP_ARG_NUM_REG + 1];
7777 enum machine_mode fmode = mode;
7778 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7780 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7782 /* Currently, we only ever need one reg here because complex
7783 doubles are split. */
7784 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7785 && (fmode == TFmode || fmode == TDmode));
7787 /* Long double or _Decimal128 split over regs and memory. */
7788 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7791 /* Do we also need to pass this arg in the parameter save
7794 && (cum->nargs_prototype <= 0
7795 || (DEFAULT_ABI == ABI_AIX
7797 && align_words >= GP_ARG_NUM_REG)));
7799 if (!needs_psave && mode == fmode)
7800 return gen_rtx_REG (fmode, cum->fregno);
7805 /* Describe the part that goes in gprs or the stack.
7806 This piece must come first, before the fprs. */
7807 if (align_words < GP_ARG_NUM_REG)
7809 unsigned long n_words = rs6000_arg_size (mode, type);
7811 if (align_words + n_words > GP_ARG_NUM_REG
7812 || (TARGET_32BIT && TARGET_POWERPC64))
7814 /* If this is partially on the stack, then we only
7815 include the portion actually in registers here. */
7816 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7819 if (align_words + n_words > GP_ARG_NUM_REG)
7820 /* Not all of the arg fits in gprs. Say that it
7821 goes in memory too, using a magic NULL_RTX
7822 component. Also see comment in
7823 rs6000_mixed_function_arg for why the normal
7824 function_arg_partial_nregs scheme doesn't work
7826 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7830 r = gen_rtx_REG (rmode,
7831 GP_ARG_MIN_REG + align_words);
7832 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7833 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7835 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7839 /* The whole arg fits in gprs. */
7840 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7841 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7845 /* It's entirely in memory. */
7846 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7849 /* Describe where this piece goes in the fprs. */
7850 r = gen_rtx_REG (fmode, cum->fregno);
7851 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7853 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7855 else if (align_words < GP_ARG_NUM_REG)
7857 if (TARGET_32BIT && TARGET_POWERPC64)
7858 return rs6000_mixed_function_arg (mode, type, align_words);
7860 if (mode == BLKmode)
7863 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7870 /* For an arg passed partly in registers and partly in memory, this is
7871 the number of bytes passed in registers. For args passed entirely in
7872 registers or entirely in memory, zero. When an arg is described by a
7873 PARALLEL, perhaps using more than one register type, this function
7874 returns the number of bytes used by the first element of the PARALLEL. */
7877 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7878 tree type, bool named)
7883 if (DEFAULT_ABI == ABI_V4)
7886 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7887 && cum->nargs_prototype >= 0)
7890 /* In this complicated case we just disable the partial_nregs code. */
7891 if (rs6000_darwin64_abi && mode == BLKmode
7892 && TREE_CODE (type) == RECORD_TYPE
7893 && int_size_in_bytes (type) > 0)
7896 align_words = rs6000_parm_start (mode, type, cum->words);
7898 if (USE_FP_FOR_ARG_P (cum, mode, type))
7900 /* If we are passing this arg in the fixed parameter save area
7901 (gprs or memory) as well as fprs, then this function should
7902 return the number of partial bytes passed in the parameter
7903 save area rather than partial bytes passed in fprs. */
7905 && (cum->nargs_prototype <= 0
7906 || (DEFAULT_ABI == ABI_AIX
7908 && align_words >= GP_ARG_NUM_REG)))
7910 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7911 > FP_ARG_MAX_REG + 1)
7912 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7913 else if (cum->nargs_prototype >= 0)
7917 if (align_words < GP_ARG_NUM_REG
7918 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7919 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7921 if (ret != 0 && TARGET_DEBUG_ARG)
7922 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7927 /* A C expression that indicates when an argument must be passed by
7928 reference. If nonzero for an argument, a copy of that argument is
7929 made in memory and a pointer to the argument is passed instead of
7930 the argument itself. The pointer is passed in whatever way is
7931 appropriate for passing a pointer to that type.
7933 Under V.4, aggregates and long double are passed by reference.
7935 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7936 reference unless the AltiVec vector extension ABI is in force.
7938 As an extension to all ABIs, variable sized types are passed by
7942 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7943 enum machine_mode mode, const_tree type,
7944 bool named ATTRIBUTE_UNUSED)
7946 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7948 if (TARGET_DEBUG_ARG)
7949 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7956 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7958 if (TARGET_DEBUG_ARG)
7959 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7963 if (int_size_in_bytes (type) < 0)
7965 if (TARGET_DEBUG_ARG)
7966 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7970 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7971 modes only exist for GCC vector types if -maltivec. */
7972 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7974 if (TARGET_DEBUG_ARG)
7975 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7979 /* Pass synthetic vectors in memory. */
7980 if (TREE_CODE (type) == VECTOR_TYPE
7981 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7983 static bool warned_for_pass_big_vectors = false;
7984 if (TARGET_DEBUG_ARG)
7985 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7986 if (!warned_for_pass_big_vectors)
7988 warning (0, "GCC vector passed by reference: "
7989 "non-standard ABI extension with no compatibility guarantee");
7990 warned_for_pass_big_vectors = true;
7999 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8002 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8007 for (i = 0; i < nregs; i++)
8009 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8010 if (reload_completed)
8012 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8015 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8016 i * GET_MODE_SIZE (reg_mode));
8019 tem = replace_equiv_address (tem, XEXP (tem, 0));
8023 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8027 /* Perform any needed actions needed for a function that is receiving a
8028 variable number of arguments.
8032 MODE and TYPE are the mode and type of the current parameter.
8034 PRETEND_SIZE is a variable that should be set to the amount of stack
8035 that must be pushed by the prolog to pretend that our caller pushed
8038 Normally, this macro will push all remaining incoming registers on the
8039 stack and set PRETEND_SIZE to the length of the registers pushed. */
8042 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8043 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8046 CUMULATIVE_ARGS next_cum;
8047 int reg_size = TARGET_32BIT ? 4 : 8;
8048 rtx save_area = NULL_RTX, mem;
8049 int first_reg_offset;
8052 /* Skip the last named argument. */
8054 function_arg_advance (&next_cum, mode, type, 1, 0);
8056 if (DEFAULT_ABI == ABI_V4)
8058 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8062 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8063 HOST_WIDE_INT offset = 0;
8065 /* Try to optimize the size of the varargs save area.
8066 The ABI requires that ap.reg_save_area is doubleword
8067 aligned, but we don't need to allocate space for all
8068 the bytes, only those to which we actually will save
8070 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8071 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8072 if (TARGET_HARD_FLOAT && TARGET_FPRS
8073 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8074 && cfun->va_list_fpr_size)
8077 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8078 * UNITS_PER_FP_WORD;
8079 if (cfun->va_list_fpr_size
8080 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8081 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8083 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8084 * UNITS_PER_FP_WORD;
8088 offset = -((first_reg_offset * reg_size) & ~7);
8089 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8091 gpr_reg_num = cfun->va_list_gpr_size;
8092 if (reg_size == 4 && (first_reg_offset & 1))
8095 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8098 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8100 - (int) (GP_ARG_NUM_REG * reg_size);
8102 if (gpr_size + fpr_size)
8105 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8106 gcc_assert (GET_CODE (reg_save_area) == MEM);
8107 reg_save_area = XEXP (reg_save_area, 0);
8108 if (GET_CODE (reg_save_area) == PLUS)
8110 gcc_assert (XEXP (reg_save_area, 0)
8111 == virtual_stack_vars_rtx);
8112 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8113 offset += INTVAL (XEXP (reg_save_area, 1));
8116 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8119 cfun->machine->varargs_save_offset = offset;
8120 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8125 first_reg_offset = next_cum.words;
8126 save_area = virtual_incoming_args_rtx;
8128 if (targetm.calls.must_pass_in_stack (mode, type))
8129 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8132 set = get_varargs_alias_set ();
8133 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8134 && cfun->va_list_gpr_size)
8136 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8138 if (va_list_gpr_counter_field)
8140 /* V4 va_list_gpr_size counts number of registers needed. */
8141 if (nregs > cfun->va_list_gpr_size)
8142 nregs = cfun->va_list_gpr_size;
8146 /* char * va_list instead counts number of bytes needed. */
8147 if (nregs > cfun->va_list_gpr_size / reg_size)
8148 nregs = cfun->va_list_gpr_size / reg_size;
8151 mem = gen_rtx_MEM (BLKmode,
8152 plus_constant (save_area,
8153 first_reg_offset * reg_size));
8154 MEM_NOTRAP_P (mem) = 1;
8155 set_mem_alias_set (mem, set);
8156 set_mem_align (mem, BITS_PER_WORD);
8158 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8162 /* Save FP registers if needed. */
8163 if (DEFAULT_ABI == ABI_V4
8164 && TARGET_HARD_FLOAT && TARGET_FPRS
8166 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8167 && cfun->va_list_fpr_size)
8169 int fregno = next_cum.fregno, nregs;
8170 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8171 rtx lab = gen_label_rtx ();
8172 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8173 * UNITS_PER_FP_WORD);
8176 (gen_rtx_SET (VOIDmode,
8178 gen_rtx_IF_THEN_ELSE (VOIDmode,
8179 gen_rtx_NE (VOIDmode, cr1,
8181 gen_rtx_LABEL_REF (VOIDmode, lab),
8185 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8186 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8188 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8190 plus_constant (save_area, off));
8191 MEM_NOTRAP_P (mem) = 1;
8192 set_mem_alias_set (mem, set);
8193 set_mem_align (mem, GET_MODE_ALIGNMENT (
8194 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8195 ? DFmode : SFmode));
8196 emit_move_insn (mem, gen_rtx_REG (
8197 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8198 ? DFmode : SFmode, fregno));
8205 /* Create the va_list data type. */
8208 rs6000_build_builtin_va_list (void)
8210 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8212 /* For AIX, prefer 'char *' because that's what the system
8213 header files like. */
8214 if (DEFAULT_ABI != ABI_V4)
8215 return build_pointer_type (char_type_node);
8217 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8218 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8219 get_identifier ("__va_list_tag"), record);
8221 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8222 unsigned_char_type_node);
8223 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8224 unsigned_char_type_node);
8225 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8227 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8228 get_identifier ("reserved"), short_unsigned_type_node);
8229 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8230 get_identifier ("overflow_arg_area"),
8232 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8233 get_identifier ("reg_save_area"),
8236 va_list_gpr_counter_field = f_gpr;
8237 va_list_fpr_counter_field = f_fpr;
8239 DECL_FIELD_CONTEXT (f_gpr) = record;
8240 DECL_FIELD_CONTEXT (f_fpr) = record;
8241 DECL_FIELD_CONTEXT (f_res) = record;
8242 DECL_FIELD_CONTEXT (f_ovf) = record;
8243 DECL_FIELD_CONTEXT (f_sav) = record;
8245 TREE_CHAIN (record) = type_decl;
8246 TYPE_NAME (record) = type_decl;
8247 TYPE_FIELDS (record) = f_gpr;
8248 TREE_CHAIN (f_gpr) = f_fpr;
8249 TREE_CHAIN (f_fpr) = f_res;
8250 TREE_CHAIN (f_res) = f_ovf;
8251 TREE_CHAIN (f_ovf) = f_sav;
8253 layout_type (record);
8255 /* The correct type is an array type of one element. */
8256 return build_array_type (record, build_index_type (size_zero_node));
8259 /* Implement va_start. */
8262 rs6000_va_start (tree valist, rtx nextarg)
8264 HOST_WIDE_INT words, n_gpr, n_fpr;
8265 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8266 tree gpr, fpr, ovf, sav, t;
8268 /* Only SVR4 needs something special. */
8269 if (DEFAULT_ABI != ABI_V4)
8271 std_expand_builtin_va_start (valist, nextarg);
8275 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8276 f_fpr = TREE_CHAIN (f_gpr);
8277 f_res = TREE_CHAIN (f_fpr);
8278 f_ovf = TREE_CHAIN (f_res);
8279 f_sav = TREE_CHAIN (f_ovf);
8281 valist = build_va_arg_indirect_ref (valist);
8282 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8283 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8285 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8287 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8290 /* Count number of gp and fp argument registers used. */
8291 words = crtl->args.info.words;
8292 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8294 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8297 if (TARGET_DEBUG_ARG)
8298 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8299 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8300 words, n_gpr, n_fpr);
8302 if (cfun->va_list_gpr_size)
8304 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8305 build_int_cst (NULL_TREE, n_gpr));
8306 TREE_SIDE_EFFECTS (t) = 1;
8307 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8310 if (cfun->va_list_fpr_size)
8312 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8313 build_int_cst (NULL_TREE, n_fpr));
8314 TREE_SIDE_EFFECTS (t) = 1;
8315 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8318 /* Find the overflow area. */
8319 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8321 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8322 size_int (words * UNITS_PER_WORD));
8323 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8324 TREE_SIDE_EFFECTS (t) = 1;
8325 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8327 /* If there were no va_arg invocations, don't set up the register
8329 if (!cfun->va_list_gpr_size
8330 && !cfun->va_list_fpr_size
8331 && n_gpr < GP_ARG_NUM_REG
8332 && n_fpr < FP_ARG_V4_MAX_REG)
8335 /* Find the register save area. */
8336 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8337 if (cfun->machine->varargs_save_offset)
8338 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8339 size_int (cfun->machine->varargs_save_offset));
8340 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8341 TREE_SIDE_EFFECTS (t) = 1;
8342 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8345 /* Implement va_arg. */
8348 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8351 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8352 tree gpr, fpr, ovf, sav, reg, t, u;
8353 int size, rsize, n_reg, sav_ofs, sav_scale;
8354 tree lab_false, lab_over, addr;
8356 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8360 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8362 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8363 return build_va_arg_indirect_ref (t);
8366 if (DEFAULT_ABI != ABI_V4)
8368 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8370 tree elem_type = TREE_TYPE (type);
8371 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8372 int elem_size = GET_MODE_SIZE (elem_mode);
8374 if (elem_size < UNITS_PER_WORD)
8376 tree real_part, imag_part;
8377 gimple_seq post = NULL;
8379 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8381 /* Copy the value into a temporary, lest the formal temporary
8382 be reused out from under us. */
8383 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8384 gimple_seq_add_seq (pre_p, post);
8386 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8389 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8393 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8396 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8397 f_fpr = TREE_CHAIN (f_gpr);
8398 f_res = TREE_CHAIN (f_fpr);
8399 f_ovf = TREE_CHAIN (f_res);
8400 f_sav = TREE_CHAIN (f_ovf);
8402 valist = build_va_arg_indirect_ref (valist);
8403 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8404 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8406 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8408 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8411 size = int_size_in_bytes (type);
8412 rsize = (size + 3) / 4;
8415 if (TARGET_HARD_FLOAT && TARGET_FPRS
8416 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8417 || (TARGET_DOUBLE_FLOAT
8418 && (TYPE_MODE (type) == DFmode
8419 || TYPE_MODE (type) == TFmode
8420 || TYPE_MODE (type) == SDmode
8421 || TYPE_MODE (type) == DDmode
8422 || TYPE_MODE (type) == TDmode))))
8424 /* FP args go in FP registers, if present. */
8426 n_reg = (size + 7) / 8;
8427 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8428 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8429 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8434 /* Otherwise into GP registers. */
8443 /* Pull the value out of the saved registers.... */
8446 addr = create_tmp_var (ptr_type_node, "addr");
8448 /* AltiVec vectors never go in registers when -mabi=altivec. */
8449 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8453 lab_false = create_artificial_label (input_location);
8454 lab_over = create_artificial_label (input_location);
8456 /* Long long and SPE vectors are aligned in the registers.
8457 As are any other 2 gpr item such as complex int due to a
8458 historical mistake. */
8460 if (n_reg == 2 && reg == gpr)
8463 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8464 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8465 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8466 unshare_expr (reg), u);
8468 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8469 reg number is 0 for f1, so we want to make it odd. */
8470 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8472 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8473 build_int_cst (TREE_TYPE (reg), 1));
8474 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8477 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8478 t = build2 (GE_EXPR, boolean_type_node, u, t);
8479 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8480 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8481 gimplify_and_add (t, pre_p);
8485 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8487 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8488 build_int_cst (TREE_TYPE (reg), n_reg));
8489 u = fold_convert (sizetype, u);
8490 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8491 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8493 /* _Decimal32 varargs are located in the second word of the 64-bit
8494 FP register for 32-bit binaries. */
8495 if (!TARGET_POWERPC64
8496 && TARGET_HARD_FLOAT && TARGET_FPRS
8497 && TYPE_MODE (type) == SDmode)
8498 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8500 gimplify_assign (addr, t, pre_p);
8502 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8504 stmt = gimple_build_label (lab_false);
8505 gimple_seq_add_stmt (pre_p, stmt);
8507 if ((n_reg == 2 && !regalign) || n_reg > 2)
8509 /* Ensure that we don't find any more args in regs.
8510 Alignment has taken care of for special cases. */
8511 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8515 /* ... otherwise out of the overflow area. */
8517 /* Care for on-stack alignment if needed. */
8521 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8522 t = fold_convert (sizetype, t);
8523 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8525 t = fold_convert (TREE_TYPE (ovf), t);
8527 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8529 gimplify_assign (unshare_expr (addr), t, pre_p);
8531 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8532 gimplify_assign (unshare_expr (ovf), t, pre_p);
8536 stmt = gimple_build_label (lab_over);
8537 gimple_seq_add_stmt (pre_p, stmt);
8540 if (STRICT_ALIGNMENT
8541 && (TYPE_ALIGN (type)
8542 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8544 /* The value (of type complex double, for example) may not be
8545 aligned in memory in the saved registers, so copy via a
8546 temporary. (This is the same code as used for SPARC.) */
8547 tree tmp = create_tmp_var (type, "va_arg_tmp");
8548 tree dest_addr = build_fold_addr_expr (tmp);
8550 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8551 3, dest_addr, addr, size_int (rsize * 4));
8553 gimplify_and_add (copy, pre_p);
8557 addr = fold_convert (ptrtype, addr);
8558 return build_va_arg_indirect_ref (addr);
8564 def_builtin (int mask, const char *name, tree type, int code)
8566 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8569 if (rs6000_builtin_decls[code])
8570 fatal_error ("internal error: builtin function to %s already processed.",
8573 rs6000_builtin_decls[code] = t =
8574 add_builtin_function (name, type, code, BUILT_IN_MD,
8577 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8578 switch (builtin_classify[code])
8583 /* assume builtin can do anything. */
8584 case RS6000_BTC_MISC:
8587 /* const function, function only depends on the inputs. */
8588 case RS6000_BTC_CONST:
8589 TREE_READONLY (t) = 1;
8590 TREE_NOTHROW (t) = 1;
8593 /* pure function, function can read global memory. */
8594 case RS6000_BTC_PURE:
8595 DECL_PURE_P (t) = 1;
8596 TREE_NOTHROW (t) = 1;
8599 /* Function is a math function. If rounding mode is on, then treat
8600 the function as not reading global memory, but it can have
8601 arbitrary side effects. If it is off, then assume the function is
8602 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8603 attribute in builtin-attribute.def that is used for the math
8605 case RS6000_BTC_FP_PURE:
8606 TREE_NOTHROW (t) = 1;
8607 if (flag_rounding_math)
8609 DECL_PURE_P (t) = 1;
8610 DECL_IS_NOVOPS (t) = 1;
8613 TREE_READONLY (t) = 1;
8619 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8621 static const struct builtin_description bdesc_3arg[] =
8623 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8624 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8625 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8626 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8627 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8628 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8629 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8630 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8631 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8632 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8633 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8634 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8635 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8636 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8637 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8638 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8639 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8640 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8641 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8642 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8643 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8644 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8645 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8646 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8647 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8648 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8649 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8650 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8651 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8652 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8653 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8659 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8660 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8663 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8664 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8665 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8666 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8667 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8668 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8669 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8670 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8671 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8672 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8673 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8675 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8676 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8677 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8678 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8680 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8681 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8682 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8683 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8688 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8689 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8690 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8691 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8692 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8693 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8694 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8695 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8696 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8697 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8699 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8700 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8701 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8702 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8703 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8704 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8705 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8706 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8707 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8708 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8710 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8711 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8712 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8713 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8714 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8715 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8716 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8717 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8718 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8720 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8721 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8722 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8723 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8724 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8725 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8726 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8728 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8729 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8730 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8731 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8732 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8733 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8734 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8735 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8736 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8739 /* DST operations: void foo (void *, const int, const char). */
8741 static const struct builtin_description bdesc_dst[] =
8743 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8744 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8745 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8746 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8754 /* Simple binary operations: VECc = foo (VECa, VECb). */
8756 static struct builtin_description bdesc_2arg[] =
8758 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8759 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8760 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8761 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8762 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8763 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8764 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8765 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8766 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8767 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8768 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8769 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8770 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8771 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8772 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8773 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8774 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8775 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8776 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8777 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8778 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8779 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8780 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8781 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8782 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8783 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8784 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8785 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8786 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8787 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8788 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8789 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8790 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8791 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8792 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8793 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8794 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8795 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8796 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8797 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8798 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8799 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8800 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8803 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8804 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8805 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8806 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8807 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8808 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8809 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8810 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8811 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8812 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8813 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8814 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8815 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8816 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8817 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8818 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8819 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8820 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8821 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8822 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8823 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8824 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8825 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8826 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8827 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8828 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8829 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8830 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8831 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8832 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8833 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8834 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8835 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8836 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8837 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8838 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8839 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8840 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8841 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8842 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8846 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8847 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8848 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8849 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8850 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8851 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8852 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8853 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8856 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8857 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8858 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8859 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8860 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8861 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8862 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8863 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8864 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8865 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8866 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8867 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8871 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8872 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8873 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8875 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8876 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8877 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8878 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8879 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8880 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8881 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8882 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8883 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8884 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8885 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8887 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8888 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8889 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8890 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8891 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8892 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8893 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8894 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8895 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8896 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8897 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8899 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8900 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8901 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8902 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8903 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8904 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8906 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8907 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8908 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8909 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8910 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8911 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8912 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8913 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8915 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8916 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8928 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8929 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8955 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8956 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8971 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8972 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8989 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8990 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9023 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9024 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9042 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9044 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9045 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9047 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9048 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9049 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9050 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9051 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9052 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9053 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9054 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9055 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9056 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9058 /* Place holder, leave as first spe builtin. */
9059 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9060 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9061 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9062 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9063 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9064 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9065 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9066 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9067 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9068 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9069 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9070 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9071 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9072 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9073 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9074 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9075 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9076 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9077 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9078 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9079 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9080 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9081 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9082 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9083 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9084 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9085 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9086 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9087 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9088 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9089 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9090 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9091 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9092 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9093 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9094 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9095 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9096 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9097 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9098 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9099 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9100 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9101 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9102 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9103 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9104 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9105 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9106 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9107 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9108 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9109 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9110 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9111 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9112 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9113 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9114 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9115 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9116 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9117 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9118 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9119 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9120 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9121 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9122 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9123 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9124 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9125 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9126 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9127 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9128 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9129 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9130 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9131 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9132 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9133 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9134 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9135 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9136 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9137 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9138 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9139 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9140 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9141 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9142 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9143 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9144 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9145 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9146 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9147 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9148 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9149 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9150 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9151 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9152 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9153 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9154 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9155 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9156 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9157 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9158 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9159 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9160 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9161 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9162 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9163 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9164 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9165 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9166 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9167 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9169 /* SPE binary operations expecting a 5-bit unsigned literal. */
9170 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9172 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9173 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9174 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9175 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9176 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9177 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9178 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9179 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9180 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9181 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9182 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9183 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9184 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9185 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9186 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9187 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9188 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9189 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9190 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9191 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9192 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9193 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9194 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9195 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9196 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9197 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9199 /* Place-holder. Leave as last binary SPE builtin. */
9200 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9203 /* AltiVec predicates. */
9205 struct builtin_description_predicates
9207 const unsigned int mask;
9208 const enum insn_code icode;
9209 const char *const name;
9210 const enum rs6000_builtins code;
9213 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9215 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9216 ALTIVEC_BUILTIN_VCMPBFP_P },
9217 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9218 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9219 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9220 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9221 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9222 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9223 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9224 ALTIVEC_BUILTIN_VCMPEQUW_P },
9225 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9226 ALTIVEC_BUILTIN_VCMPGTSW_P },
9227 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9228 ALTIVEC_BUILTIN_VCMPGTUW_P },
9229 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9230 ALTIVEC_BUILTIN_VCMPEQUH_P },
9231 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9232 ALTIVEC_BUILTIN_VCMPGTSH_P },
9233 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9234 ALTIVEC_BUILTIN_VCMPGTUH_P },
9235 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9236 ALTIVEC_BUILTIN_VCMPEQUB_P },
9237 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9238 ALTIVEC_BUILTIN_VCMPGTSB_P },
9239 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9240 ALTIVEC_BUILTIN_VCMPGTUB_P },
9242 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9243 VSX_BUILTIN_XVCMPEQSP_P },
9244 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9245 VSX_BUILTIN_XVCMPGESP_P },
9246 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9247 VSX_BUILTIN_XVCMPGTSP_P },
9248 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9249 VSX_BUILTIN_XVCMPEQDP_P },
9250 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9251 VSX_BUILTIN_XVCMPGEDP_P },
9252 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9253 VSX_BUILTIN_XVCMPGTDP_P },
9255 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9256 ALTIVEC_BUILTIN_VCMPEQ_P },
9257 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9258 ALTIVEC_BUILTIN_VCMPGT_P },
9259 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9260 ALTIVEC_BUILTIN_VCMPGE_P }
9263 /* SPE predicates. */
9264 static struct builtin_description bdesc_spe_predicates[] =
9266 /* Place-holder. Leave as first. */
9267 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9268 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9269 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9270 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9271 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9272 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9273 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9274 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9275 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9276 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9277 /* Place-holder. Leave as last. */
9278 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9281 /* SPE evsel predicates. */
9282 static struct builtin_description bdesc_spe_evsel[] =
9284 /* Place-holder. Leave as first. */
9285 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9286 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9287 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9288 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9289 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9290 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9291 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9292 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9293 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9294 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9295 /* Place-holder. Leave as last. */
9296 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9299 /* PAIRED predicates. */
9300 static const struct builtin_description bdesc_paired_preds[] =
9302 /* Place-holder. Leave as first. */
9303 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9304 /* Place-holder. Leave as last. */
9305 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9308 /* ABS* operations. */
9310 static const struct builtin_description bdesc_abs[] =
9312 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9313 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9314 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9315 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9316 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9317 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9318 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9319 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9320 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9321 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9322 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9325 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9328 static struct builtin_description bdesc_1arg[] =
9330 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9331 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9332 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9333 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9334 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9335 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9336 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9337 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9338 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9339 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9340 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9341 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9342 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9343 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9344 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9345 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9346 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9348 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9349 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9350 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9351 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9352 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9353 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9355 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9356 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9357 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9358 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9359 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9360 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9362 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9363 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9364 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9365 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9366 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9367 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9369 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9370 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9371 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9372 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9373 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9374 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9376 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9377 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9378 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9379 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9381 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9382 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9383 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9384 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9385 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9386 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9387 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9388 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9389 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9391 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9392 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9393 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9394 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9395 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9396 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9397 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9398 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9399 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9401 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9402 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9403 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9404 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9405 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9427 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9428 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9429 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9431 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9432 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9433 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9434 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9436 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9437 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9438 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9439 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9440 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9441 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9442 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9443 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9444 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9445 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9446 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9447 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9448 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9449 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9450 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9451 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9452 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9453 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9454 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9455 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9456 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9457 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9458 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9459 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9460 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9461 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9462 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9463 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9464 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9465 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9467 /* Place-holder. Leave as last unary SPE builtin. */
9468 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9470 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9471 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9472 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9473 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9474 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9478 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9481 tree arg0 = CALL_EXPR_ARG (exp, 0);
9482 rtx op0 = expand_normal (arg0);
9483 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9484 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9486 if (icode == CODE_FOR_nothing)
9487 /* Builtin not supported on this processor. */
9490 /* If we got invalid arguments bail out before generating bad rtl. */
9491 if (arg0 == error_mark_node)
9494 if (icode == CODE_FOR_altivec_vspltisb
9495 || icode == CODE_FOR_altivec_vspltish
9496 || icode == CODE_FOR_altivec_vspltisw
9497 || icode == CODE_FOR_spe_evsplatfi
9498 || icode == CODE_FOR_spe_evsplati)
9500 /* Only allow 5-bit *signed* literals. */
9501 if (GET_CODE (op0) != CONST_INT
9502 || INTVAL (op0) > 15
9503 || INTVAL (op0) < -16)
9505 error ("argument 1 must be a 5-bit signed literal");
9511 || GET_MODE (target) != tmode
9512 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9513 target = gen_reg_rtx (tmode);
9515 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9516 op0 = copy_to_mode_reg (mode0, op0);
9518 pat = GEN_FCN (icode) (target, op0);
9527 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9529 rtx pat, scratch1, scratch2;
9530 tree arg0 = CALL_EXPR_ARG (exp, 0);
9531 rtx op0 = expand_normal (arg0);
9532 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9533 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9535 /* If we have invalid arguments, bail out before generating bad rtl. */
9536 if (arg0 == error_mark_node)
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 scratch1 = gen_reg_rtx (mode0);
9548 scratch2 = gen_reg_rtx (mode0);
9550 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9559 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9562 tree arg0 = CALL_EXPR_ARG (exp, 0);
9563 tree arg1 = CALL_EXPR_ARG (exp, 1);
9564 rtx op0 = expand_normal (arg0);
9565 rtx op1 = expand_normal (arg1);
9566 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9567 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9568 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9570 if (icode == CODE_FOR_nothing)
9571 /* Builtin not supported on this processor. */
9574 /* If we got invalid arguments bail out before generating bad rtl. */
9575 if (arg0 == error_mark_node || arg1 == error_mark_node)
9578 if (icode == CODE_FOR_altivec_vcfux
9579 || icode == CODE_FOR_altivec_vcfsx
9580 || icode == CODE_FOR_altivec_vctsxs
9581 || icode == CODE_FOR_altivec_vctuxs
9582 || icode == CODE_FOR_altivec_vspltb
9583 || icode == CODE_FOR_altivec_vsplth
9584 || icode == CODE_FOR_altivec_vspltw
9585 || icode == CODE_FOR_spe_evaddiw
9586 || icode == CODE_FOR_spe_evldd
9587 || icode == CODE_FOR_spe_evldh
9588 || icode == CODE_FOR_spe_evldw
9589 || icode == CODE_FOR_spe_evlhhesplat
9590 || icode == CODE_FOR_spe_evlhhossplat
9591 || icode == CODE_FOR_spe_evlhhousplat
9592 || icode == CODE_FOR_spe_evlwhe
9593 || icode == CODE_FOR_spe_evlwhos
9594 || icode == CODE_FOR_spe_evlwhou
9595 || icode == CODE_FOR_spe_evlwhsplat
9596 || icode == CODE_FOR_spe_evlwwsplat
9597 || icode == CODE_FOR_spe_evrlwi
9598 || icode == CODE_FOR_spe_evslwi
9599 || icode == CODE_FOR_spe_evsrwis
9600 || icode == CODE_FOR_spe_evsubifw
9601 || icode == CODE_FOR_spe_evsrwiu)
9603 /* Only allow 5-bit unsigned literals. */
9605 if (TREE_CODE (arg1) != INTEGER_CST
9606 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9608 error ("argument 2 must be a 5-bit unsigned literal");
9614 || GET_MODE (target) != tmode
9615 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9616 target = gen_reg_rtx (tmode);
9618 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9619 op0 = copy_to_mode_reg (mode0, op0);
9620 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9621 op1 = copy_to_mode_reg (mode1, op1);
9623 pat = GEN_FCN (icode) (target, op0, op1);
9632 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9635 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9636 tree arg0 = CALL_EXPR_ARG (exp, 1);
9637 tree arg1 = CALL_EXPR_ARG (exp, 2);
9638 rtx op0 = expand_normal (arg0);
9639 rtx op1 = expand_normal (arg1);
9640 enum machine_mode tmode = SImode;
9641 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9642 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9645 if (TREE_CODE (cr6_form) != INTEGER_CST)
9647 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9651 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9653 gcc_assert (mode0 == mode1);
9655 /* If we have invalid arguments, bail out before generating bad rtl. */
9656 if (arg0 == error_mark_node || arg1 == error_mark_node)
9660 || GET_MODE (target) != tmode
9661 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9662 target = gen_reg_rtx (tmode);
9664 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9665 op0 = copy_to_mode_reg (mode0, op0);
9666 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9667 op1 = copy_to_mode_reg (mode1, op1);
9669 scratch = gen_reg_rtx (mode0);
9671 pat = GEN_FCN (icode) (scratch, op0, op1);
9676 /* The vec_any* and vec_all* predicates use the same opcodes for two
9677 different operations, but the bits in CR6 will be different
9678 depending on what information we want. So we have to play tricks
9679 with CR6 to get the right bits out.
9681 If you think this is disgusting, look at the specs for the
9682 AltiVec predicates. */
9684 switch (cr6_form_int)
9687 emit_insn (gen_cr6_test_for_zero (target));
9690 emit_insn (gen_cr6_test_for_zero_reverse (target));
9693 emit_insn (gen_cr6_test_for_lt (target));
9696 emit_insn (gen_cr6_test_for_lt_reverse (target));
9699 error ("argument 1 of __builtin_altivec_predicate is out of range");
9707 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9710 tree arg0 = CALL_EXPR_ARG (exp, 0);
9711 tree arg1 = CALL_EXPR_ARG (exp, 1);
9712 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9713 enum machine_mode mode0 = Pmode;
9714 enum machine_mode mode1 = Pmode;
9715 rtx op0 = expand_normal (arg0);
9716 rtx op1 = expand_normal (arg1);
9718 if (icode == CODE_FOR_nothing)
9719 /* Builtin not supported on this processor. */
9722 /* If we got invalid arguments bail out before generating bad rtl. */
9723 if (arg0 == error_mark_node || arg1 == error_mark_node)
9727 || GET_MODE (target) != tmode
9728 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9729 target = gen_reg_rtx (tmode);
9731 op1 = copy_to_mode_reg (mode1, op1);
9733 if (op0 == const0_rtx)
9735 addr = gen_rtx_MEM (tmode, op1);
9739 op0 = copy_to_mode_reg (mode0, op0);
9740 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9743 pat = GEN_FCN (icode) (target, addr);
9753 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9756 tree arg0 = CALL_EXPR_ARG (exp, 0);
9757 tree arg1 = CALL_EXPR_ARG (exp, 1);
9758 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9759 enum machine_mode mode0 = Pmode;
9760 enum machine_mode mode1 = Pmode;
9761 rtx op0 = expand_normal (arg0);
9762 rtx op1 = expand_normal (arg1);
9764 if (icode == CODE_FOR_nothing)
9765 /* Builtin not supported on this processor. */
9768 /* If we got invalid arguments bail out before generating bad rtl. */
9769 if (arg0 == error_mark_node || arg1 == error_mark_node)
9773 || GET_MODE (target) != tmode
9774 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9775 target = gen_reg_rtx (tmode);
9777 op1 = copy_to_mode_reg (mode1, op1);
9779 if (op0 == const0_rtx)
9781 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9785 op0 = copy_to_mode_reg (mode0, op0);
9786 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9789 pat = GEN_FCN (icode) (target, addr);
9799 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9801 tree arg0 = CALL_EXPR_ARG (exp, 0);
9802 tree arg1 = CALL_EXPR_ARG (exp, 1);
9803 tree arg2 = CALL_EXPR_ARG (exp, 2);
9804 rtx op0 = expand_normal (arg0);
9805 rtx op1 = expand_normal (arg1);
9806 rtx op2 = expand_normal (arg2);
9808 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9809 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9810 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9812 /* Invalid arguments. Bail before doing anything stoopid! */
9813 if (arg0 == error_mark_node
9814 || arg1 == error_mark_node
9815 || arg2 == error_mark_node)
9818 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9819 op0 = copy_to_mode_reg (mode2, op0);
9820 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9821 op1 = copy_to_mode_reg (mode0, op1);
9822 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9823 op2 = copy_to_mode_reg (mode1, op2);
9825 pat = GEN_FCN (icode) (op1, op2, op0);
9832 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9834 tree arg0 = CALL_EXPR_ARG (exp, 0);
9835 tree arg1 = CALL_EXPR_ARG (exp, 1);
9836 tree arg2 = CALL_EXPR_ARG (exp, 2);
9837 rtx op0 = expand_normal (arg0);
9838 rtx op1 = expand_normal (arg1);
9839 rtx op2 = expand_normal (arg2);
9841 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9842 enum machine_mode mode1 = Pmode;
9843 enum machine_mode mode2 = Pmode;
9845 /* Invalid arguments. Bail before doing anything stoopid! */
9846 if (arg0 == error_mark_node
9847 || arg1 == error_mark_node
9848 || arg2 == error_mark_node)
9851 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9852 op0 = copy_to_mode_reg (tmode, op0);
9854 op2 = copy_to_mode_reg (mode2, op2);
9856 if (op1 == const0_rtx)
9858 addr = gen_rtx_MEM (tmode, op2);
9862 op1 = copy_to_mode_reg (mode1, op1);
9863 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9866 pat = GEN_FCN (icode) (addr, op0);
9873 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9875 tree arg0 = CALL_EXPR_ARG (exp, 0);
9876 tree arg1 = CALL_EXPR_ARG (exp, 1);
9877 tree arg2 = CALL_EXPR_ARG (exp, 2);
9878 rtx op0 = expand_normal (arg0);
9879 rtx op1 = expand_normal (arg1);
9880 rtx op2 = expand_normal (arg2);
9882 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9883 enum machine_mode mode1 = Pmode;
9884 enum machine_mode mode2 = Pmode;
9886 /* Invalid arguments. Bail before doing anything stoopid! */
9887 if (arg0 == error_mark_node
9888 || arg1 == error_mark_node
9889 || arg2 == error_mark_node)
9892 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9893 op0 = copy_to_mode_reg (tmode, op0);
9895 op2 = copy_to_mode_reg (mode2, op2);
9897 if (op1 == const0_rtx)
9899 addr = gen_rtx_MEM (tmode, op2);
9903 op1 = copy_to_mode_reg (mode1, op1);
9904 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9907 pat = GEN_FCN (icode) (addr, op0);
9914 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9917 tree arg0 = CALL_EXPR_ARG (exp, 0);
9918 tree arg1 = CALL_EXPR_ARG (exp, 1);
9919 tree arg2 = CALL_EXPR_ARG (exp, 2);
9920 rtx op0 = expand_normal (arg0);
9921 rtx op1 = expand_normal (arg1);
9922 rtx op2 = expand_normal (arg2);
9923 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9924 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9925 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9926 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9928 if (icode == CODE_FOR_nothing)
9929 /* Builtin not supported on this processor. */
9932 /* If we got invalid arguments bail out before generating bad rtl. */
9933 if (arg0 == error_mark_node
9934 || arg1 == error_mark_node
9935 || arg2 == error_mark_node)
9940 case CODE_FOR_altivec_vsldoi_v4sf:
9941 case CODE_FOR_altivec_vsldoi_v4si:
9942 case CODE_FOR_altivec_vsldoi_v8hi:
9943 case CODE_FOR_altivec_vsldoi_v16qi:
9944 /* Only allow 4-bit unsigned literals. */
9946 if (TREE_CODE (arg2) != INTEGER_CST
9947 || TREE_INT_CST_LOW (arg2) & ~0xf)
9949 error ("argument 3 must be a 4-bit unsigned literal");
9954 case CODE_FOR_vsx_xxpermdi_v2df:
9955 case CODE_FOR_vsx_xxpermdi_v2di:
9956 case CODE_FOR_vsx_xxsldwi_v16qi:
9957 case CODE_FOR_vsx_xxsldwi_v8hi:
9958 case CODE_FOR_vsx_xxsldwi_v4si:
9959 case CODE_FOR_vsx_xxsldwi_v4sf:
9960 case CODE_FOR_vsx_xxsldwi_v2di:
9961 case CODE_FOR_vsx_xxsldwi_v2df:
9962 /* Only allow 2-bit unsigned literals. */
9964 if (TREE_CODE (arg2) != INTEGER_CST
9965 || TREE_INT_CST_LOW (arg2) & ~0x3)
9967 error ("argument 3 must be a 2-bit unsigned literal");
9972 case CODE_FOR_vsx_set_v2df:
9973 case CODE_FOR_vsx_set_v2di:
9974 /* Only allow 1-bit unsigned literals. */
9976 if (TREE_CODE (arg2) != INTEGER_CST
9977 || TREE_INT_CST_LOW (arg2) & ~0x1)
9979 error ("argument 3 must be a 1-bit unsigned literal");
9989 || GET_MODE (target) != tmode
9990 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9991 target = gen_reg_rtx (tmode);
9993 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9994 op0 = copy_to_mode_reg (mode0, op0);
9995 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9996 op1 = copy_to_mode_reg (mode1, op1);
9997 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9998 op2 = copy_to_mode_reg (mode2, op2);
10000 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10001 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10003 pat = GEN_FCN (icode) (target, op0, op1, op2);
10011 /* Expand the lvx builtins. */
10013 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10015 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10016 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10018 enum machine_mode tmode, mode0;
10020 enum insn_code icode;
10024 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10025 icode = CODE_FOR_vector_load_v16qi;
10027 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10028 icode = CODE_FOR_vector_load_v8hi;
10030 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10031 icode = CODE_FOR_vector_load_v4si;
10033 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10034 icode = CODE_FOR_vector_load_v4sf;
10037 *expandedp = false;
10043 arg0 = CALL_EXPR_ARG (exp, 0);
10044 op0 = expand_normal (arg0);
10045 tmode = insn_data[icode].operand[0].mode;
10046 mode0 = insn_data[icode].operand[1].mode;
10049 || GET_MODE (target) != tmode
10050 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10051 target = gen_reg_rtx (tmode);
10053 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10054 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10056 pat = GEN_FCN (icode) (target, op0);
10063 /* Expand the stvx builtins. */
10065 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10068 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10069 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10071 enum machine_mode mode0, mode1;
10073 enum insn_code icode;
10077 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10078 icode = CODE_FOR_vector_store_v16qi;
10080 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10081 icode = CODE_FOR_vector_store_v8hi;
10083 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10084 icode = CODE_FOR_vector_store_v4si;
10086 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10087 icode = CODE_FOR_vector_store_v4sf;
10090 *expandedp = false;
10094 arg0 = CALL_EXPR_ARG (exp, 0);
10095 arg1 = CALL_EXPR_ARG (exp, 1);
10096 op0 = expand_normal (arg0);
10097 op1 = expand_normal (arg1);
10098 mode0 = insn_data[icode].operand[0].mode;
10099 mode1 = insn_data[icode].operand[1].mode;
10101 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10102 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10103 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10104 op1 = copy_to_mode_reg (mode1, op1);
10106 pat = GEN_FCN (icode) (op0, op1);
10114 /* Expand the dst builtins. */
10116 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10119 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10120 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10121 tree arg0, arg1, arg2;
10122 enum machine_mode mode0, mode1, mode2;
10123 rtx pat, op0, op1, op2;
10124 const struct builtin_description *d;
10127 *expandedp = false;
10129 /* Handle DST variants. */
10131 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10132 if (d->code == fcode)
10134 arg0 = CALL_EXPR_ARG (exp, 0);
10135 arg1 = CALL_EXPR_ARG (exp, 1);
10136 arg2 = CALL_EXPR_ARG (exp, 2);
10137 op0 = expand_normal (arg0);
10138 op1 = expand_normal (arg1);
10139 op2 = expand_normal (arg2);
10140 mode0 = insn_data[d->icode].operand[0].mode;
10141 mode1 = insn_data[d->icode].operand[1].mode;
10142 mode2 = insn_data[d->icode].operand[2].mode;
10144 /* Invalid arguments, bail out before generating bad rtl. */
10145 if (arg0 == error_mark_node
10146 || arg1 == error_mark_node
10147 || arg2 == error_mark_node)
10152 if (TREE_CODE (arg2) != INTEGER_CST
10153 || TREE_INT_CST_LOW (arg2) & ~0x3)
10155 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10159 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10160 op0 = copy_to_mode_reg (Pmode, op0);
10161 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10162 op1 = copy_to_mode_reg (mode1, op1);
10164 pat = GEN_FCN (d->icode) (op0, op1, op2);
10174 /* Expand vec_init builtin. */
10176 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10178 enum machine_mode tmode = TYPE_MODE (type);
10179 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10180 int i, n_elt = GET_MODE_NUNITS (tmode);
10181 rtvec v = rtvec_alloc (n_elt);
10183 gcc_assert (VECTOR_MODE_P (tmode));
10184 gcc_assert (n_elt == call_expr_nargs (exp));
10186 for (i = 0; i < n_elt; ++i)
10188 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10189 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10192 if (!target || !register_operand (target, tmode))
10193 target = gen_reg_rtx (tmode);
10195 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10199 /* Return the integer constant in ARG. Constrain it to be in the range
10200 of the subparts of VEC_TYPE; issue an error if not. */
10203 get_element_number (tree vec_type, tree arg)
10205 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10207 if (!host_integerp (arg, 1)
10208 || (elt = tree_low_cst (arg, 1), elt > max))
10210 error ("selector must be an integer constant in the range 0..%wi", max);
10217 /* Expand vec_set builtin. */
10219 altivec_expand_vec_set_builtin (tree exp)
10221 enum machine_mode tmode, mode1;
10222 tree arg0, arg1, arg2;
10226 arg0 = CALL_EXPR_ARG (exp, 0);
10227 arg1 = CALL_EXPR_ARG (exp, 1);
10228 arg2 = CALL_EXPR_ARG (exp, 2);
10230 tmode = TYPE_MODE (TREE_TYPE (arg0));
10231 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10232 gcc_assert (VECTOR_MODE_P (tmode));
10234 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10235 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10236 elt = get_element_number (TREE_TYPE (arg0), arg2);
10238 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10239 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10241 op0 = force_reg (tmode, op0);
10242 op1 = force_reg (mode1, op1);
10244 rs6000_expand_vector_set (op0, op1, elt);
10249 /* Expand vec_ext builtin. */
10251 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10253 enum machine_mode tmode, mode0;
10258 arg0 = CALL_EXPR_ARG (exp, 0);
10259 arg1 = CALL_EXPR_ARG (exp, 1);
10261 op0 = expand_normal (arg0);
10262 elt = get_element_number (TREE_TYPE (arg0), arg1);
10264 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10265 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10266 gcc_assert (VECTOR_MODE_P (mode0));
10268 op0 = force_reg (mode0, op0);
10270 if (optimize || !target || !register_operand (target, tmode))
10271 target = gen_reg_rtx (tmode);
10273 rs6000_expand_vector_extract (target, op0, elt);
10278 /* Expand the builtin in EXP and store the result in TARGET. Store
10279 true in *EXPANDEDP if we found a builtin to expand. */
10281 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10283 const struct builtin_description *d;
10284 const struct builtin_description_predicates *dp;
10286 enum insn_code icode;
10287 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10290 enum machine_mode tmode, mode0;
10291 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10293 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10294 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10295 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10296 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10299 error ("unresolved overload for Altivec builtin %qF", fndecl);
10303 target = altivec_expand_ld_builtin (exp, target, expandedp);
10307 target = altivec_expand_st_builtin (exp, target, expandedp);
10311 target = altivec_expand_dst_builtin (exp, target, expandedp);
10319 case ALTIVEC_BUILTIN_STVX:
10320 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10321 case ALTIVEC_BUILTIN_STVEBX:
10322 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10323 case ALTIVEC_BUILTIN_STVEHX:
10324 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10325 case ALTIVEC_BUILTIN_STVEWX:
10326 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10327 case ALTIVEC_BUILTIN_STVXL:
10328 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10330 case ALTIVEC_BUILTIN_STVLX:
10331 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10332 case ALTIVEC_BUILTIN_STVLXL:
10333 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10334 case ALTIVEC_BUILTIN_STVRX:
10335 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10336 case ALTIVEC_BUILTIN_STVRXL:
10337 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10339 case ALTIVEC_BUILTIN_MFVSCR:
10340 icode = CODE_FOR_altivec_mfvscr;
10341 tmode = insn_data[icode].operand[0].mode;
10344 || GET_MODE (target) != tmode
10345 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10346 target = gen_reg_rtx (tmode);
10348 pat = GEN_FCN (icode) (target);
10354 case ALTIVEC_BUILTIN_MTVSCR:
10355 icode = CODE_FOR_altivec_mtvscr;
10356 arg0 = CALL_EXPR_ARG (exp, 0);
10357 op0 = expand_normal (arg0);
10358 mode0 = insn_data[icode].operand[0].mode;
10360 /* If we got invalid arguments bail out before generating bad rtl. */
10361 if (arg0 == error_mark_node)
10364 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10365 op0 = copy_to_mode_reg (mode0, op0);
10367 pat = GEN_FCN (icode) (op0);
10372 case ALTIVEC_BUILTIN_DSSALL:
10373 emit_insn (gen_altivec_dssall ());
10376 case ALTIVEC_BUILTIN_DSS:
10377 icode = CODE_FOR_altivec_dss;
10378 arg0 = CALL_EXPR_ARG (exp, 0);
10380 op0 = expand_normal (arg0);
10381 mode0 = insn_data[icode].operand[0].mode;
10383 /* If we got invalid arguments bail out before generating bad rtl. */
10384 if (arg0 == error_mark_node)
10387 if (TREE_CODE (arg0) != INTEGER_CST
10388 || TREE_INT_CST_LOW (arg0) & ~0x3)
10390 error ("argument to dss must be a 2-bit unsigned literal");
10394 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10395 op0 = copy_to_mode_reg (mode0, op0);
10397 emit_insn (gen_altivec_dss (op0));
10400 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10401 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10402 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10403 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10404 case VSX_BUILTIN_VEC_INIT_V2DF:
10405 case VSX_BUILTIN_VEC_INIT_V2DI:
10406 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10408 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10409 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10410 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10411 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10412 case VSX_BUILTIN_VEC_SET_V2DF:
10413 case VSX_BUILTIN_VEC_SET_V2DI:
10414 return altivec_expand_vec_set_builtin (exp);
10416 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10417 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10418 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10419 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10420 case VSX_BUILTIN_VEC_EXT_V2DF:
10421 case VSX_BUILTIN_VEC_EXT_V2DI:
10422 return altivec_expand_vec_ext_builtin (exp, target);
10426 /* Fall through. */
10429 /* Expand abs* operations. */
10431 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10432 if (d->code == fcode)
10433 return altivec_expand_abs_builtin (d->icode, exp, target);
10435 /* Expand the AltiVec predicates. */
10436 dp = bdesc_altivec_preds;
10437 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10438 if (dp->code == fcode)
10439 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10441 /* LV* are funky. We initialized them differently. */
10444 case ALTIVEC_BUILTIN_LVSL:
10445 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10446 exp, target, false);
10447 case ALTIVEC_BUILTIN_LVSR:
10448 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10449 exp, target, false);
10450 case ALTIVEC_BUILTIN_LVEBX:
10451 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10452 exp, target, false);
10453 case ALTIVEC_BUILTIN_LVEHX:
10454 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10455 exp, target, false);
10456 case ALTIVEC_BUILTIN_LVEWX:
10457 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10458 exp, target, false);
10459 case ALTIVEC_BUILTIN_LVXL:
10460 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10461 exp, target, false);
10462 case ALTIVEC_BUILTIN_LVX:
10463 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10464 exp, target, false);
10465 case ALTIVEC_BUILTIN_LVLX:
10466 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10467 exp, target, true);
10468 case ALTIVEC_BUILTIN_LVLXL:
10469 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10470 exp, target, true);
10471 case ALTIVEC_BUILTIN_LVRX:
10472 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10473 exp, target, true);
10474 case ALTIVEC_BUILTIN_LVRXL:
10475 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10476 exp, target, true);
10479 /* Fall through. */
10482 *expandedp = false;
10486 /* Expand the builtin in EXP and store the result in TARGET. Store
10487 true in *EXPANDEDP if we found a builtin to expand. */
10489 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10491 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10492 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10493 const struct builtin_description *d;
10500 case PAIRED_BUILTIN_STX:
10501 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10502 case PAIRED_BUILTIN_LX:
10503 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10506 /* Fall through. */
10509 /* Expand the paired predicates. */
10510 d = bdesc_paired_preds;
10511 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10512 if (d->code == fcode)
10513 return paired_expand_predicate_builtin (d->icode, exp, target);
10515 *expandedp = false;
10519 /* Binops that need to be initialized manually, but can be expanded
10520 automagically by rs6000_expand_binop_builtin. */
10521 static struct builtin_description bdesc_2arg_spe[] =
10523 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10524 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10525 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10526 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10527 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10528 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10529 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10530 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10531 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10532 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10533 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10534 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10535 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10536 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10537 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10538 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10539 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10540 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10541 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10542 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10543 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10544 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10547 /* Expand the builtin in EXP and store the result in TARGET. Store
10548 true in *EXPANDEDP if we found a builtin to expand.
10550 This expands the SPE builtins that are not simple unary and binary
10553 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10555 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10557 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10558 enum insn_code icode;
10559 enum machine_mode tmode, mode0;
10561 struct builtin_description *d;
10566 /* Syntax check for a 5-bit unsigned immediate. */
10569 case SPE_BUILTIN_EVSTDD:
10570 case SPE_BUILTIN_EVSTDH:
10571 case SPE_BUILTIN_EVSTDW:
10572 case SPE_BUILTIN_EVSTWHE:
10573 case SPE_BUILTIN_EVSTWHO:
10574 case SPE_BUILTIN_EVSTWWE:
10575 case SPE_BUILTIN_EVSTWWO:
10576 arg1 = CALL_EXPR_ARG (exp, 2);
10577 if (TREE_CODE (arg1) != INTEGER_CST
10578 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10580 error ("argument 2 must be a 5-bit unsigned literal");
10588 /* The evsplat*i instructions are not quite generic. */
10591 case SPE_BUILTIN_EVSPLATFI:
10592 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10594 case SPE_BUILTIN_EVSPLATI:
10595 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10601 d = (struct builtin_description *) bdesc_2arg_spe;
10602 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10603 if (d->code == fcode)
10604 return rs6000_expand_binop_builtin (d->icode, exp, target);
10606 d = (struct builtin_description *) bdesc_spe_predicates;
10607 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10608 if (d->code == fcode)
10609 return spe_expand_predicate_builtin (d->icode, exp, target);
10611 d = (struct builtin_description *) bdesc_spe_evsel;
10612 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10613 if (d->code == fcode)
10614 return spe_expand_evsel_builtin (d->icode, exp, target);
10618 case SPE_BUILTIN_EVSTDDX:
10619 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10620 case SPE_BUILTIN_EVSTDHX:
10621 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10622 case SPE_BUILTIN_EVSTDWX:
10623 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10624 case SPE_BUILTIN_EVSTWHEX:
10625 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10626 case SPE_BUILTIN_EVSTWHOX:
10627 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10628 case SPE_BUILTIN_EVSTWWEX:
10629 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10630 case SPE_BUILTIN_EVSTWWOX:
10631 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10632 case SPE_BUILTIN_EVSTDD:
10633 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10634 case SPE_BUILTIN_EVSTDH:
10635 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10636 case SPE_BUILTIN_EVSTDW:
10637 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10638 case SPE_BUILTIN_EVSTWHE:
10639 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10640 case SPE_BUILTIN_EVSTWHO:
10641 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10642 case SPE_BUILTIN_EVSTWWE:
10643 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10644 case SPE_BUILTIN_EVSTWWO:
10645 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10646 case SPE_BUILTIN_MFSPEFSCR:
10647 icode = CODE_FOR_spe_mfspefscr;
10648 tmode = insn_data[icode].operand[0].mode;
10651 || GET_MODE (target) != tmode
10652 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10653 target = gen_reg_rtx (tmode);
10655 pat = GEN_FCN (icode) (target);
10660 case SPE_BUILTIN_MTSPEFSCR:
10661 icode = CODE_FOR_spe_mtspefscr;
10662 arg0 = CALL_EXPR_ARG (exp, 0);
10663 op0 = expand_normal (arg0);
10664 mode0 = insn_data[icode].operand[0].mode;
10666 if (arg0 == error_mark_node)
10669 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10670 op0 = copy_to_mode_reg (mode0, op0);
10672 pat = GEN_FCN (icode) (op0);
10680 *expandedp = false;
10685 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10687 rtx pat, scratch, tmp;
10688 tree form = CALL_EXPR_ARG (exp, 0);
10689 tree arg0 = CALL_EXPR_ARG (exp, 1);
10690 tree arg1 = CALL_EXPR_ARG (exp, 2);
10691 rtx op0 = expand_normal (arg0);
10692 rtx op1 = expand_normal (arg1);
10693 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10694 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10696 enum rtx_code code;
10698 if (TREE_CODE (form) != INTEGER_CST)
10700 error ("argument 1 of __builtin_paired_predicate must be a constant");
10704 form_int = TREE_INT_CST_LOW (form);
10706 gcc_assert (mode0 == mode1);
10708 if (arg0 == error_mark_node || arg1 == error_mark_node)
10712 || GET_MODE (target) != SImode
10713 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10714 target = gen_reg_rtx (SImode);
10715 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10716 op0 = copy_to_mode_reg (mode0, op0);
10717 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10718 op1 = copy_to_mode_reg (mode1, op1);
10720 scratch = gen_reg_rtx (CCFPmode);
10722 pat = GEN_FCN (icode) (scratch, op0, op1);
10744 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10747 error ("argument 1 of __builtin_paired_predicate is out of range");
10751 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10752 emit_move_insn (target, tmp);
10757 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10759 rtx pat, scratch, tmp;
10760 tree form = CALL_EXPR_ARG (exp, 0);
10761 tree arg0 = CALL_EXPR_ARG (exp, 1);
10762 tree arg1 = CALL_EXPR_ARG (exp, 2);
10763 rtx op0 = expand_normal (arg0);
10764 rtx op1 = expand_normal (arg1);
10765 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10766 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10768 enum rtx_code code;
10770 if (TREE_CODE (form) != INTEGER_CST)
10772 error ("argument 1 of __builtin_spe_predicate must be a constant");
10776 form_int = TREE_INT_CST_LOW (form);
10778 gcc_assert (mode0 == mode1);
10780 if (arg0 == error_mark_node || arg1 == error_mark_node)
10784 || GET_MODE (target) != SImode
10785 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10786 target = gen_reg_rtx (SImode);
10788 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10789 op0 = copy_to_mode_reg (mode0, op0);
10790 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10791 op1 = copy_to_mode_reg (mode1, op1);
10793 scratch = gen_reg_rtx (CCmode);
10795 pat = GEN_FCN (icode) (scratch, op0, op1);
10800 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10801 _lower_. We use one compare, but look in different bits of the
10802 CR for each variant.
10804 There are 2 elements in each SPE simd type (upper/lower). The CR
10805 bits are set as follows:
10807 BIT0 | BIT 1 | BIT 2 | BIT 3
10808 U | L | (U | L) | (U & L)
10810 So, for an "all" relationship, BIT 3 would be set.
10811 For an "any" relationship, BIT 2 would be set. Etc.
10813 Following traditional nomenclature, these bits map to:
10815 BIT0 | BIT 1 | BIT 2 | BIT 3
10818 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10823 /* All variant. OV bit. */
10825 /* We need to get to the OV bit, which is the ORDERED bit. We
10826 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10827 that's ugly and will make validate_condition_mode die.
10828 So let's just use another pattern. */
10829 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10831 /* Any variant. EQ bit. */
10835 /* Upper variant. LT bit. */
10839 /* Lower variant. GT bit. */
10844 error ("argument 1 of __builtin_spe_predicate is out of range");
10848 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10849 emit_move_insn (target, tmp);
10854 /* The evsel builtins look like this:
10856 e = __builtin_spe_evsel_OP (a, b, c, d);
10858 and work like this:
10860 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10861 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10865 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10868 tree arg0 = CALL_EXPR_ARG (exp, 0);
10869 tree arg1 = CALL_EXPR_ARG (exp, 1);
10870 tree arg2 = CALL_EXPR_ARG (exp, 2);
10871 tree arg3 = CALL_EXPR_ARG (exp, 3);
10872 rtx op0 = expand_normal (arg0);
10873 rtx op1 = expand_normal (arg1);
10874 rtx op2 = expand_normal (arg2);
10875 rtx op3 = expand_normal (arg3);
10876 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10877 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10879 gcc_assert (mode0 == mode1);
10881 if (arg0 == error_mark_node || arg1 == error_mark_node
10882 || arg2 == error_mark_node || arg3 == error_mark_node)
10886 || GET_MODE (target) != mode0
10887 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10888 target = gen_reg_rtx (mode0);
10890 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10891 op0 = copy_to_mode_reg (mode0, op0);
10892 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10893 op1 = copy_to_mode_reg (mode0, op1);
10894 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10895 op2 = copy_to_mode_reg (mode0, op2);
10896 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10897 op3 = copy_to_mode_reg (mode0, op3);
10899 /* Generate the compare. */
10900 scratch = gen_reg_rtx (CCmode);
10901 pat = GEN_FCN (icode) (scratch, op0, op1);
10906 if (mode0 == V2SImode)
10907 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10909 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10914 /* Expand an expression EXP that calls a built-in function,
10915 with result going to TARGET if that's convenient
10916 (and in mode MODE if that's convenient).
10917 SUBTARGET may be used as the target for computing one of EXP's operands.
10918 IGNORE is nonzero if the value is to be ignored. */
10921 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10922 enum machine_mode mode ATTRIBUTE_UNUSED,
10923 int ignore ATTRIBUTE_UNUSED)
10925 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10926 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10927 const struct builtin_description *d;
10932 if (fcode == RS6000_BUILTIN_RECIP)
10933 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10935 if (fcode == RS6000_BUILTIN_RECIPF)
10936 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10938 if (fcode == RS6000_BUILTIN_RSQRTF)
10939 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10941 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10942 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10944 if (fcode == POWER7_BUILTIN_BPERMD)
10945 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10946 ? CODE_FOR_bpermd_di
10947 : CODE_FOR_bpermd_si), exp, target);
10949 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10950 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10952 int icode = (int) CODE_FOR_altivec_lvsr;
10953 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10954 enum machine_mode mode = insn_data[icode].operand[1].mode;
10958 gcc_assert (TARGET_ALTIVEC);
10960 arg = CALL_EXPR_ARG (exp, 0);
10961 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10962 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10963 addr = memory_address (mode, op);
10964 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10968 /* For the load case need to negate the address. */
10969 op = gen_reg_rtx (GET_MODE (addr));
10970 emit_insn (gen_rtx_SET (VOIDmode, op,
10971 gen_rtx_NEG (GET_MODE (addr), addr)));
10973 op = gen_rtx_MEM (mode, op);
10976 || GET_MODE (target) != tmode
10977 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10978 target = gen_reg_rtx (tmode);
10980 /*pat = gen_altivec_lvsr (target, op);*/
10981 pat = GEN_FCN (icode) (target, op);
10989 /* FIXME: There's got to be a nicer way to handle this case than
10990 constructing a new CALL_EXPR. */
10991 if (fcode == ALTIVEC_BUILTIN_VCFUX
10992 || fcode == ALTIVEC_BUILTIN_VCFSX
10993 || fcode == ALTIVEC_BUILTIN_VCTUXS
10994 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10996 if (call_expr_nargs (exp) == 1)
10997 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10998 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11001 if (TARGET_ALTIVEC)
11003 ret = altivec_expand_builtin (exp, target, &success);
11010 ret = spe_expand_builtin (exp, target, &success);
11015 if (TARGET_PAIRED_FLOAT)
11017 ret = paired_expand_builtin (exp, target, &success);
11023 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11025 /* Handle simple unary operations. */
11026 d = (struct builtin_description *) bdesc_1arg;
11027 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11028 if (d->code == fcode)
11029 return rs6000_expand_unop_builtin (d->icode, exp, target);
11031 /* Handle simple binary operations. */
11032 d = (struct builtin_description *) bdesc_2arg;
11033 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11034 if (d->code == fcode)
11035 return rs6000_expand_binop_builtin (d->icode, exp, target);
11037 /* Handle simple ternary operations. */
11039 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11040 if (d->code == fcode)
11041 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11043 gcc_unreachable ();
11047 rs6000_init_builtins (void)
11051 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11052 V2SF_type_node = build_vector_type (float_type_node, 2);
11053 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11054 V2DF_type_node = build_vector_type (double_type_node, 2);
11055 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11056 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11057 V4SF_type_node = build_vector_type (float_type_node, 4);
11058 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11059 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11061 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11062 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11063 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11064 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11066 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11067 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11068 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11069 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11071 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11072 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11073 'vector unsigned short'. */
11075 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11076 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11077 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11078 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11079 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11081 long_integer_type_internal_node = long_integer_type_node;
11082 long_unsigned_type_internal_node = long_unsigned_type_node;
11083 intQI_type_internal_node = intQI_type_node;
11084 uintQI_type_internal_node = unsigned_intQI_type_node;
11085 intHI_type_internal_node = intHI_type_node;
11086 uintHI_type_internal_node = unsigned_intHI_type_node;
11087 intSI_type_internal_node = intSI_type_node;
11088 uintSI_type_internal_node = unsigned_intSI_type_node;
11089 intDI_type_internal_node = intDI_type_node;
11090 uintDI_type_internal_node = unsigned_intDI_type_node;
11091 float_type_internal_node = float_type_node;
11092 double_type_internal_node = float_type_node;
11093 void_type_internal_node = void_type_node;
11095 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11097 builtin_mode_to_type[QImode][0] = integer_type_node;
11098 builtin_mode_to_type[HImode][0] = integer_type_node;
11099 builtin_mode_to_type[SImode][0] = intSI_type_node;
11100 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11101 builtin_mode_to_type[DImode][0] = intDI_type_node;
11102 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11103 builtin_mode_to_type[SFmode][0] = float_type_node;
11104 builtin_mode_to_type[DFmode][0] = double_type_node;
11105 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11106 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11107 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11108 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11109 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11110 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11111 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11112 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11113 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11114 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11115 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11116 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11117 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11119 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11120 get_identifier ("__bool char"),
11121 bool_char_type_node);
11122 TYPE_NAME (bool_char_type_node) = tdecl;
11123 (*lang_hooks.decls.pushdecl) (tdecl);
11124 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11125 get_identifier ("__bool short"),
11126 bool_short_type_node);
11127 TYPE_NAME (bool_short_type_node) = tdecl;
11128 (*lang_hooks.decls.pushdecl) (tdecl);
11129 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11130 get_identifier ("__bool int"),
11131 bool_int_type_node);
11132 TYPE_NAME (bool_int_type_node) = tdecl;
11133 (*lang_hooks.decls.pushdecl) (tdecl);
11134 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11136 TYPE_NAME (pixel_type_node) = tdecl;
11137 (*lang_hooks.decls.pushdecl) (tdecl);
11139 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11140 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11141 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11142 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11143 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11145 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11146 get_identifier ("__vector unsigned char"),
11147 unsigned_V16QI_type_node);
11148 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11149 (*lang_hooks.decls.pushdecl) (tdecl);
11150 tdecl = build_decl (BUILTINS_LOCATION,
11151 TYPE_DECL, get_identifier ("__vector signed char"),
11153 TYPE_NAME (V16QI_type_node) = tdecl;
11154 (*lang_hooks.decls.pushdecl) (tdecl);
11155 tdecl = build_decl (BUILTINS_LOCATION,
11156 TYPE_DECL, get_identifier ("__vector __bool char"),
11157 bool_V16QI_type_node);
11158 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11159 (*lang_hooks.decls.pushdecl) (tdecl);
11161 tdecl = build_decl (BUILTINS_LOCATION,
11162 TYPE_DECL, get_identifier ("__vector unsigned short"),
11163 unsigned_V8HI_type_node);
11164 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11165 (*lang_hooks.decls.pushdecl) (tdecl);
11166 tdecl = build_decl (BUILTINS_LOCATION,
11167 TYPE_DECL, get_identifier ("__vector signed short"),
11169 TYPE_NAME (V8HI_type_node) = tdecl;
11170 (*lang_hooks.decls.pushdecl) (tdecl);
11171 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11172 get_identifier ("__vector __bool short"),
11173 bool_V8HI_type_node);
11174 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11175 (*lang_hooks.decls.pushdecl) (tdecl);
11177 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11178 get_identifier ("__vector unsigned int"),
11179 unsigned_V4SI_type_node);
11180 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11181 (*lang_hooks.decls.pushdecl) (tdecl);
11182 tdecl = build_decl (BUILTINS_LOCATION,
11183 TYPE_DECL, get_identifier ("__vector signed int"),
11185 TYPE_NAME (V4SI_type_node) = tdecl;
11186 (*lang_hooks.decls.pushdecl) (tdecl);
11187 tdecl = build_decl (BUILTINS_LOCATION,
11188 TYPE_DECL, get_identifier ("__vector __bool int"),
11189 bool_V4SI_type_node);
11190 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11191 (*lang_hooks.decls.pushdecl) (tdecl);
11193 tdecl = build_decl (BUILTINS_LOCATION,
11194 TYPE_DECL, get_identifier ("__vector float"),
11196 TYPE_NAME (V4SF_type_node) = tdecl;
11197 (*lang_hooks.decls.pushdecl) (tdecl);
11198 tdecl = build_decl (BUILTINS_LOCATION,
11199 TYPE_DECL, get_identifier ("__vector __pixel"),
11200 pixel_V8HI_type_node);
11201 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11202 (*lang_hooks.decls.pushdecl) (tdecl);
11206 tdecl = build_decl (BUILTINS_LOCATION,
11207 TYPE_DECL, get_identifier ("__vector double"),
11209 TYPE_NAME (V2DF_type_node) = tdecl;
11210 (*lang_hooks.decls.pushdecl) (tdecl);
11212 tdecl = build_decl (BUILTINS_LOCATION,
11213 TYPE_DECL, get_identifier ("__vector long"),
11215 TYPE_NAME (V2DI_type_node) = tdecl;
11216 (*lang_hooks.decls.pushdecl) (tdecl);
11218 tdecl = build_decl (BUILTINS_LOCATION,
11219 TYPE_DECL, get_identifier ("__vector unsigned long"),
11220 unsigned_V2DI_type_node);
11221 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11222 (*lang_hooks.decls.pushdecl) (tdecl);
11224 tdecl = build_decl (BUILTINS_LOCATION,
11225 TYPE_DECL, get_identifier ("__vector __bool long"),
11226 bool_V2DI_type_node);
11227 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11228 (*lang_hooks.decls.pushdecl) (tdecl);
11231 if (TARGET_PAIRED_FLOAT)
11232 paired_init_builtins ();
11234 spe_init_builtins ();
11235 if (TARGET_ALTIVEC)
11236 altivec_init_builtins ();
11237 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11238 rs6000_common_init_builtins ();
11239 if (TARGET_PPC_GFXOPT)
11241 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11242 RS6000_BUILTIN_RECIPF,
11243 "__builtin_recipdivf");
11244 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11245 RS6000_BUILTIN_RECIPF);
11247 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11248 RS6000_BUILTIN_RSQRTF,
11249 "__builtin_rsqrtf");
11250 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11251 RS6000_BUILTIN_RSQRTF);
11253 if (TARGET_POPCNTB)
11255 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11256 RS6000_BUILTIN_RECIP,
11257 "__builtin_recipdiv");
11258 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11259 RS6000_BUILTIN_RECIP);
11262 if (TARGET_POPCNTD)
11264 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11265 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11266 POWER7_BUILTIN_BPERMD,
11267 "__builtin_bpermd");
11268 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11269 POWER7_BUILTIN_BPERMD);
11271 if (TARGET_POWERPC)
11273 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11274 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11275 unsigned_intHI_type_node,
11277 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11278 RS6000_BUILTIN_BSWAP_HI);
11282 /* AIX libm provides clog as __clog. */
11283 if (built_in_decls [BUILT_IN_CLOG])
11284 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11287 #ifdef SUBTARGET_INIT_BUILTINS
11288 SUBTARGET_INIT_BUILTINS;
11292 /* Returns the rs6000 builtin decl for CODE. */
11295 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11297 if (code >= RS6000_BUILTIN_COUNT)
11298 return error_mark_node;
11300 return rs6000_builtin_decls[code];
11303 /* Search through a set of builtins and enable the mask bits.
11304 DESC is an array of builtins.
11305 SIZE is the total number of builtins.
11306 START is the builtin enum at which to start.
11307 END is the builtin enum at which to end. */
11309 enable_mask_for_builtins (struct builtin_description *desc, int size,
11310 enum rs6000_builtins start,
11311 enum rs6000_builtins end)
11315 for (i = 0; i < size; ++i)
11316 if (desc[i].code == start)
11322 for (; i < size; ++i)
11324 /* Flip all the bits on. */
11325 desc[i].mask = target_flags;
11326 if (desc[i].code == end)
11332 spe_init_builtins (void)
11334 tree endlink = void_list_node;
11335 tree puint_type_node = build_pointer_type (unsigned_type_node);
11336 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11337 struct builtin_description *d;
11340 tree v2si_ftype_4_v2si
11341 = build_function_type
11342 (opaque_V2SI_type_node,
11343 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11344 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11345 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11346 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11349 tree v2sf_ftype_4_v2sf
11350 = build_function_type
11351 (opaque_V2SF_type_node,
11352 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11353 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11354 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11355 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11358 tree int_ftype_int_v2si_v2si
11359 = build_function_type
11360 (integer_type_node,
11361 tree_cons (NULL_TREE, integer_type_node,
11362 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11363 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11366 tree int_ftype_int_v2sf_v2sf
11367 = build_function_type
11368 (integer_type_node,
11369 tree_cons (NULL_TREE, integer_type_node,
11370 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11371 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11374 tree void_ftype_v2si_puint_int
11375 = build_function_type (void_type_node,
11376 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11377 tree_cons (NULL_TREE, puint_type_node,
11378 tree_cons (NULL_TREE,
11382 tree void_ftype_v2si_puint_char
11383 = build_function_type (void_type_node,
11384 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11385 tree_cons (NULL_TREE, puint_type_node,
11386 tree_cons (NULL_TREE,
11390 tree void_ftype_v2si_pv2si_int
11391 = build_function_type (void_type_node,
11392 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11393 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11394 tree_cons (NULL_TREE,
11398 tree void_ftype_v2si_pv2si_char
11399 = build_function_type (void_type_node,
11400 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11401 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11402 tree_cons (NULL_TREE,
11406 tree void_ftype_int
11407 = build_function_type (void_type_node,
11408 tree_cons (NULL_TREE, integer_type_node, endlink));
11410 tree int_ftype_void
11411 = build_function_type (integer_type_node, endlink);
11413 tree v2si_ftype_pv2si_int
11414 = build_function_type (opaque_V2SI_type_node,
11415 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11416 tree_cons (NULL_TREE, integer_type_node,
11419 tree v2si_ftype_puint_int
11420 = build_function_type (opaque_V2SI_type_node,
11421 tree_cons (NULL_TREE, puint_type_node,
11422 tree_cons (NULL_TREE, integer_type_node,
11425 tree v2si_ftype_pushort_int
11426 = build_function_type (opaque_V2SI_type_node,
11427 tree_cons (NULL_TREE, pushort_type_node,
11428 tree_cons (NULL_TREE, integer_type_node,
11431 tree v2si_ftype_signed_char
11432 = build_function_type (opaque_V2SI_type_node,
11433 tree_cons (NULL_TREE, signed_char_type_node,
11436 /* The initialization of the simple binary and unary builtins is
11437 done in rs6000_common_init_builtins, but we have to enable the
11438 mask bits here manually because we have run out of `target_flags'
11439 bits. We really need to redesign this mask business. */
11441 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11442 ARRAY_SIZE (bdesc_2arg),
11443 SPE_BUILTIN_EVADDW,
11444 SPE_BUILTIN_EVXOR);
11445 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11446 ARRAY_SIZE (bdesc_1arg),
11448 SPE_BUILTIN_EVSUBFUSIAAW);
11449 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11450 ARRAY_SIZE (bdesc_spe_predicates),
11451 SPE_BUILTIN_EVCMPEQ,
11452 SPE_BUILTIN_EVFSTSTLT);
11453 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11454 ARRAY_SIZE (bdesc_spe_evsel),
11455 SPE_BUILTIN_EVSEL_CMPGTS,
11456 SPE_BUILTIN_EVSEL_FSTSTEQ);
11458 (*lang_hooks.decls.pushdecl)
11459 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11460 get_identifier ("__ev64_opaque__"),
11461 opaque_V2SI_type_node));
11463 /* Initialize irregular SPE builtins. */
11465 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11466 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11467 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11468 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11469 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11470 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11471 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11472 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11473 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11474 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11475 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11476 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11477 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11478 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11479 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11480 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11481 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11482 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11485 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11486 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11487 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11488 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11489 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11490 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11491 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11492 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11493 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11494 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11495 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11496 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11497 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11498 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11499 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11500 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11501 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11502 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11503 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11504 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11505 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11506 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11509 d = (struct builtin_description *) bdesc_spe_predicates;
11510 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11514 switch (insn_data[d->icode].operand[1].mode)
11517 type = int_ftype_int_v2si_v2si;
11520 type = int_ftype_int_v2sf_v2sf;
11523 gcc_unreachable ();
11526 def_builtin (d->mask, d->name, type, d->code);
11529 /* Evsel predicates. */
11530 d = (struct builtin_description *) bdesc_spe_evsel;
11531 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11535 switch (insn_data[d->icode].operand[1].mode)
11538 type = v2si_ftype_4_v2si;
11541 type = v2sf_ftype_4_v2sf;
11544 gcc_unreachable ();
11547 def_builtin (d->mask, d->name, type, d->code);
11552 paired_init_builtins (void)
11554 const struct builtin_description *d;
11556 tree endlink = void_list_node;
11558 tree int_ftype_int_v2sf_v2sf
11559 = build_function_type
11560 (integer_type_node,
11561 tree_cons (NULL_TREE, integer_type_node,
11562 tree_cons (NULL_TREE, V2SF_type_node,
11563 tree_cons (NULL_TREE, V2SF_type_node,
11565 tree pcfloat_type_node =
11566 build_pointer_type (build_qualified_type
11567 (float_type_node, TYPE_QUAL_CONST));
11569 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11570 long_integer_type_node,
11573 tree void_ftype_v2sf_long_pcfloat =
11574 build_function_type_list (void_type_node,
11576 long_integer_type_node,
11581 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11582 PAIRED_BUILTIN_LX);
11585 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11586 PAIRED_BUILTIN_STX);
11589 d = bdesc_paired_preds;
11590 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11594 switch (insn_data[d->icode].operand[1].mode)
11597 type = int_ftype_int_v2sf_v2sf;
11600 gcc_unreachable ();
11603 def_builtin (d->mask, d->name, type, d->code);
11608 altivec_init_builtins (void)
11610 const struct builtin_description *d;
11611 const struct builtin_description_predicates *dp;
11615 tree pfloat_type_node = build_pointer_type (float_type_node);
11616 tree pint_type_node = build_pointer_type (integer_type_node);
11617 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11618 tree pchar_type_node = build_pointer_type (char_type_node);
11620 tree pvoid_type_node = build_pointer_type (void_type_node);
11622 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11623 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11624 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11625 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11627 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11629 tree int_ftype_opaque
11630 = build_function_type_list (integer_type_node,
11631 opaque_V4SI_type_node, NULL_TREE);
11632 tree opaque_ftype_opaque
11633 = build_function_type (integer_type_node,
11635 tree opaque_ftype_opaque_int
11636 = build_function_type_list (opaque_V4SI_type_node,
11637 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11638 tree opaque_ftype_opaque_opaque_int
11639 = build_function_type_list (opaque_V4SI_type_node,
11640 opaque_V4SI_type_node, opaque_V4SI_type_node,
11641 integer_type_node, NULL_TREE);
11642 tree int_ftype_int_opaque_opaque
11643 = build_function_type_list (integer_type_node,
11644 integer_type_node, opaque_V4SI_type_node,
11645 opaque_V4SI_type_node, NULL_TREE);
11646 tree int_ftype_int_v4si_v4si
11647 = build_function_type_list (integer_type_node,
11648 integer_type_node, V4SI_type_node,
11649 V4SI_type_node, NULL_TREE);
11650 tree v4sf_ftype_pcfloat
11651 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11652 tree void_ftype_pfloat_v4sf
11653 = build_function_type_list (void_type_node,
11654 pfloat_type_node, V4SF_type_node, NULL_TREE);
11655 tree v4si_ftype_pcint
11656 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11657 tree void_ftype_pint_v4si
11658 = build_function_type_list (void_type_node,
11659 pint_type_node, V4SI_type_node, NULL_TREE);
11660 tree v8hi_ftype_pcshort
11661 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11662 tree void_ftype_pshort_v8hi
11663 = build_function_type_list (void_type_node,
11664 pshort_type_node, V8HI_type_node, NULL_TREE);
11665 tree v16qi_ftype_pcchar
11666 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11667 tree void_ftype_pchar_v16qi
11668 = build_function_type_list (void_type_node,
11669 pchar_type_node, V16QI_type_node, NULL_TREE);
11670 tree void_ftype_v4si
11671 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11672 tree v8hi_ftype_void
11673 = build_function_type (V8HI_type_node, void_list_node);
11674 tree void_ftype_void
11675 = build_function_type (void_type_node, void_list_node);
11676 tree void_ftype_int
11677 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11679 tree opaque_ftype_long_pcvoid
11680 = build_function_type_list (opaque_V4SI_type_node,
11681 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11682 tree v16qi_ftype_long_pcvoid
11683 = build_function_type_list (V16QI_type_node,
11684 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11685 tree v8hi_ftype_long_pcvoid
11686 = build_function_type_list (V8HI_type_node,
11687 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11688 tree v4si_ftype_long_pcvoid
11689 = build_function_type_list (V4SI_type_node,
11690 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11692 tree void_ftype_opaque_long_pvoid
11693 = build_function_type_list (void_type_node,
11694 opaque_V4SI_type_node, long_integer_type_node,
11695 pvoid_type_node, NULL_TREE);
11696 tree void_ftype_v4si_long_pvoid
11697 = build_function_type_list (void_type_node,
11698 V4SI_type_node, long_integer_type_node,
11699 pvoid_type_node, NULL_TREE);
11700 tree void_ftype_v16qi_long_pvoid
11701 = build_function_type_list (void_type_node,
11702 V16QI_type_node, long_integer_type_node,
11703 pvoid_type_node, NULL_TREE);
11704 tree void_ftype_v8hi_long_pvoid
11705 = build_function_type_list (void_type_node,
11706 V8HI_type_node, long_integer_type_node,
11707 pvoid_type_node, NULL_TREE);
11708 tree int_ftype_int_v8hi_v8hi
11709 = build_function_type_list (integer_type_node,
11710 integer_type_node, V8HI_type_node,
11711 V8HI_type_node, NULL_TREE);
11712 tree int_ftype_int_v16qi_v16qi
11713 = build_function_type_list (integer_type_node,
11714 integer_type_node, V16QI_type_node,
11715 V16QI_type_node, NULL_TREE);
11716 tree int_ftype_int_v4sf_v4sf
11717 = build_function_type_list (integer_type_node,
11718 integer_type_node, V4SF_type_node,
11719 V4SF_type_node, NULL_TREE);
11720 tree int_ftype_int_v2df_v2df
11721 = build_function_type_list (integer_type_node,
11722 integer_type_node, V2DF_type_node,
11723 V2DF_type_node, NULL_TREE);
11724 tree v4si_ftype_v4si
11725 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11726 tree v8hi_ftype_v8hi
11727 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11728 tree v16qi_ftype_v16qi
11729 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11730 tree v4sf_ftype_v4sf
11731 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11732 tree v2df_ftype_v2df
11733 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11734 tree void_ftype_pcvoid_int_int
11735 = build_function_type_list (void_type_node,
11736 pcvoid_type_node, integer_type_node,
11737 integer_type_node, NULL_TREE);
11739 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11740 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11741 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11742 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11743 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11744 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11745 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11746 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11747 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11748 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11749 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11750 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11751 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11752 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11753 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11754 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11755 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11756 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11757 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11758 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11759 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11760 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11761 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11762 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11763 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11764 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11765 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11766 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11767 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11768 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11769 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11770 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11771 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11772 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11773 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11774 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11775 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11776 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11777 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11778 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11779 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11780 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11781 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11782 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11783 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11784 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11786 if (rs6000_cpu == PROCESSOR_CELL)
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11793 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11794 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11795 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11796 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11801 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11804 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11805 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11808 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11810 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11812 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11813 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11814 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11815 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11816 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11817 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11818 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11819 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11820 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11825 /* Add the DST variants. */
11827 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11828 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11830 /* Initialize the predicates. */
11831 dp = bdesc_altivec_preds;
11832 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11834 enum machine_mode mode1;
11836 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11837 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11838 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11839 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11844 mode1 = insn_data[dp->icode].operand[1].mode;
11849 type = int_ftype_int_opaque_opaque;
11852 type = int_ftype_int_v4si_v4si;
11855 type = int_ftype_int_v8hi_v8hi;
11858 type = int_ftype_int_v16qi_v16qi;
11861 type = int_ftype_int_v4sf_v4sf;
11864 type = int_ftype_int_v2df_v2df;
11867 gcc_unreachable ();
11870 def_builtin (dp->mask, dp->name, type, dp->code);
11873 /* Initialize the abs* operators. */
11875 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11877 enum machine_mode mode0;
11880 mode0 = insn_data[d->icode].operand[0].mode;
11885 type = v4si_ftype_v4si;
11888 type = v8hi_ftype_v8hi;
11891 type = v16qi_ftype_v16qi;
11894 type = v4sf_ftype_v4sf;
11897 type = v2df_ftype_v2df;
11900 gcc_unreachable ();
11903 def_builtin (d->mask, d->name, type, d->code);
11906 if (TARGET_ALTIVEC)
11910 /* Initialize target builtin that implements
11911 targetm.vectorize.builtin_mask_for_load. */
11913 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11914 v16qi_ftype_long_pcvoid,
11915 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11916 BUILT_IN_MD, NULL, NULL_TREE);
11917 TREE_READONLY (decl) = 1;
11918 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11919 altivec_builtin_mask_for_load = decl;
11922 /* Access to the vec_init patterns. */
11923 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11924 integer_type_node, integer_type_node,
11925 integer_type_node, NULL_TREE);
11926 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11927 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11929 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11930 short_integer_type_node,
11931 short_integer_type_node,
11932 short_integer_type_node,
11933 short_integer_type_node,
11934 short_integer_type_node,
11935 short_integer_type_node,
11936 short_integer_type_node, NULL_TREE);
11937 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11938 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11940 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11941 char_type_node, char_type_node,
11942 char_type_node, char_type_node,
11943 char_type_node, char_type_node,
11944 char_type_node, char_type_node,
11945 char_type_node, char_type_node,
11946 char_type_node, char_type_node,
11947 char_type_node, char_type_node,
11948 char_type_node, NULL_TREE);
11949 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11950 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11952 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11953 float_type_node, float_type_node,
11954 float_type_node, NULL_TREE);
11955 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11956 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11960 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11961 double_type_node, NULL_TREE);
11962 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11963 VSX_BUILTIN_VEC_INIT_V2DF);
11965 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11966 intDI_type_node, NULL_TREE);
11967 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11968 VSX_BUILTIN_VEC_INIT_V2DI);
11971 /* Access to the vec_set patterns. */
11972 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11974 integer_type_node, NULL_TREE);
11975 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11976 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11978 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11980 integer_type_node, NULL_TREE);
11981 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11982 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11984 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11986 integer_type_node, NULL_TREE);
11987 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11988 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11990 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11992 integer_type_node, NULL_TREE);
11993 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11994 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11998 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12000 integer_type_node, NULL_TREE);
12001 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12002 VSX_BUILTIN_VEC_SET_V2DF);
12004 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12006 integer_type_node, NULL_TREE);
12007 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12008 VSX_BUILTIN_VEC_SET_V2DI);
12011 /* Access to the vec_extract patterns. */
12012 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12013 integer_type_node, NULL_TREE);
12014 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12015 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12017 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12018 integer_type_node, NULL_TREE);
12019 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12020 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12022 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12023 integer_type_node, NULL_TREE);
12024 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12025 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12027 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12028 integer_type_node, NULL_TREE);
12029 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12030 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12034 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12035 integer_type_node, NULL_TREE);
12036 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12037 VSX_BUILTIN_VEC_EXT_V2DF);
12039 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12040 integer_type_node, NULL_TREE);
12041 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12042 VSX_BUILTIN_VEC_EXT_V2DI);
12046 /* Hash function for builtin functions with up to 3 arguments and a return
12049 builtin_hash_function (const void *hash_entry)
12053 const struct builtin_hash_struct *bh =
12054 (const struct builtin_hash_struct *) hash_entry;
12056 for (i = 0; i < 4; i++)
12058 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12059 ret = (ret * 2) + bh->uns_p[i];
12065 /* Compare builtin hash entries H1 and H2 for equivalence. */
12067 builtin_hash_eq (const void *h1, const void *h2)
12069 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12070 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12072 return ((p1->mode[0] == p2->mode[0])
12073 && (p1->mode[1] == p2->mode[1])
12074 && (p1->mode[2] == p2->mode[2])
12075 && (p1->mode[3] == p2->mode[3])
12076 && (p1->uns_p[0] == p2->uns_p[0])
12077 && (p1->uns_p[1] == p2->uns_p[1])
12078 && (p1->uns_p[2] == p2->uns_p[2])
12079 && (p1->uns_p[3] == p2->uns_p[3]));
12082 /* Map types for builtin functions with an explicit return type and up to 3
12083 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12084 of the argument. */
12086 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12087 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12088 enum rs6000_builtins builtin, const char *name)
12090 struct builtin_hash_struct h;
12091 struct builtin_hash_struct *h2;
12095 tree ret_type = NULL_TREE;
12096 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12099 /* Create builtin_hash_table. */
12100 if (builtin_hash_table == NULL)
12101 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12102 builtin_hash_eq, NULL);
12104 h.type = NULL_TREE;
12105 h.mode[0] = mode_ret;
12106 h.mode[1] = mode_arg0;
12107 h.mode[2] = mode_arg1;
12108 h.mode[3] = mode_arg2;
12114 /* If the builtin is a type that produces unsigned results or takes unsigned
12115 arguments, and it is returned as a decl for the vectorizer (such as
12116 widening multiplies, permute), make sure the arguments and return value
12117 are type correct. */
12120 /* unsigned 2 argument functions. */
12121 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12122 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12123 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12124 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12130 /* unsigned 3 argument functions. */
12131 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12132 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12133 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12134 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12135 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12136 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12137 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12138 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12139 case VSX_BUILTIN_VPERM_16QI_UNS:
12140 case VSX_BUILTIN_VPERM_8HI_UNS:
12141 case VSX_BUILTIN_VPERM_4SI_UNS:
12142 case VSX_BUILTIN_VPERM_2DI_UNS:
12143 case VSX_BUILTIN_XXSEL_16QI_UNS:
12144 case VSX_BUILTIN_XXSEL_8HI_UNS:
12145 case VSX_BUILTIN_XXSEL_4SI_UNS:
12146 case VSX_BUILTIN_XXSEL_2DI_UNS:
12153 /* signed permute functions with unsigned char mask. */
12154 case ALTIVEC_BUILTIN_VPERM_16QI:
12155 case ALTIVEC_BUILTIN_VPERM_8HI:
12156 case ALTIVEC_BUILTIN_VPERM_4SI:
12157 case ALTIVEC_BUILTIN_VPERM_4SF:
12158 case ALTIVEC_BUILTIN_VPERM_2DI:
12159 case ALTIVEC_BUILTIN_VPERM_2DF:
12160 case VSX_BUILTIN_VPERM_16QI:
12161 case VSX_BUILTIN_VPERM_8HI:
12162 case VSX_BUILTIN_VPERM_4SI:
12163 case VSX_BUILTIN_VPERM_4SF:
12164 case VSX_BUILTIN_VPERM_2DI:
12165 case VSX_BUILTIN_VPERM_2DF:
12169 /* unsigned args, signed return. */
12170 case VSX_BUILTIN_XVCVUXDDP_UNS:
12171 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12175 /* signed args, unsigned return. */
12176 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12177 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12185 /* Figure out how many args are present. */
12186 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12190 fatal_error ("internal error: builtin function %s had no type", name);
12192 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12193 if (!ret_type && h.uns_p[0])
12194 ret_type = builtin_mode_to_type[h.mode[0]][0];
12197 fatal_error ("internal error: builtin function %s had an unexpected "
12198 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12200 for (i = 0; i < num_args; i++)
12202 int m = (int) h.mode[i+1];
12203 int uns_p = h.uns_p[i+1];
12205 arg_type[i] = builtin_mode_to_type[m][uns_p];
12206 if (!arg_type[i] && uns_p)
12207 arg_type[i] = builtin_mode_to_type[m][0];
12210 fatal_error ("internal error: builtin function %s, argument %d "
12211 "had unexpected argument type %s", name, i,
12212 GET_MODE_NAME (m));
12215 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12216 if (*found == NULL)
12218 h2 = GGC_NEW (struct builtin_hash_struct);
12220 *found = (void *)h2;
12221 args = void_list_node;
12223 for (i = num_args - 1; i >= 0; i--)
12224 args = tree_cons (NULL_TREE, arg_type[i], args);
12226 h2->type = build_function_type (ret_type, args);
12229 return ((struct builtin_hash_struct *)(*found))->type;
12233 rs6000_common_init_builtins (void)
12235 const struct builtin_description *d;
12238 tree opaque_ftype_opaque = NULL_TREE;
12239 tree opaque_ftype_opaque_opaque = NULL_TREE;
12240 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12241 tree v2si_ftype_qi = NULL_TREE;
12242 tree v2si_ftype_v2si_qi = NULL_TREE;
12243 tree v2si_ftype_int_qi = NULL_TREE;
12245 if (!TARGET_PAIRED_FLOAT)
12247 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12248 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12251 /* Add the ternary operators. */
12253 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12256 int mask = d->mask;
12258 if ((mask != 0 && (mask & target_flags) == 0)
12259 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12262 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12263 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12264 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12265 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12267 if (! (type = opaque_ftype_opaque_opaque_opaque))
12268 type = opaque_ftype_opaque_opaque_opaque
12269 = build_function_type_list (opaque_V4SI_type_node,
12270 opaque_V4SI_type_node,
12271 opaque_V4SI_type_node,
12272 opaque_V4SI_type_node,
12277 enum insn_code icode = d->icode;
12278 if (d->name == 0 || icode == CODE_FOR_nothing)
12281 type = builtin_function_type (insn_data[icode].operand[0].mode,
12282 insn_data[icode].operand[1].mode,
12283 insn_data[icode].operand[2].mode,
12284 insn_data[icode].operand[3].mode,
12288 def_builtin (d->mask, d->name, type, d->code);
12291 /* Add the binary operators. */
12293 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12295 enum machine_mode mode0, mode1, mode2;
12297 int mask = d->mask;
12299 if ((mask != 0 && (mask & target_flags) == 0)
12300 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12303 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12304 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12305 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12306 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12308 if (! (type = opaque_ftype_opaque_opaque))
12309 type = opaque_ftype_opaque_opaque
12310 = build_function_type_list (opaque_V4SI_type_node,
12311 opaque_V4SI_type_node,
12312 opaque_V4SI_type_node,
12317 enum insn_code icode = d->icode;
12318 if (d->name == 0 || icode == CODE_FOR_nothing)
12321 mode0 = insn_data[icode].operand[0].mode;
12322 mode1 = insn_data[icode].operand[1].mode;
12323 mode2 = insn_data[icode].operand[2].mode;
12325 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12327 if (! (type = v2si_ftype_v2si_qi))
12328 type = v2si_ftype_v2si_qi
12329 = build_function_type_list (opaque_V2SI_type_node,
12330 opaque_V2SI_type_node,
12335 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12336 && mode2 == QImode)
12338 if (! (type = v2si_ftype_int_qi))
12339 type = v2si_ftype_int_qi
12340 = build_function_type_list (opaque_V2SI_type_node,
12347 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12351 def_builtin (d->mask, d->name, type, d->code);
12354 /* Add the simple unary operators. */
12355 d = (struct builtin_description *) bdesc_1arg;
12356 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12358 enum machine_mode mode0, mode1;
12360 int mask = d->mask;
12362 if ((mask != 0 && (mask & target_flags) == 0)
12363 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12366 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12367 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12368 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12369 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12371 if (! (type = opaque_ftype_opaque))
12372 type = opaque_ftype_opaque
12373 = build_function_type_list (opaque_V4SI_type_node,
12374 opaque_V4SI_type_node,
12379 enum insn_code icode = d->icode;
12380 if (d->name == 0 || icode == CODE_FOR_nothing)
12383 mode0 = insn_data[icode].operand[0].mode;
12384 mode1 = insn_data[icode].operand[1].mode;
12386 if (mode0 == V2SImode && mode1 == QImode)
12388 if (! (type = v2si_ftype_qi))
12389 type = v2si_ftype_qi
12390 = build_function_type_list (opaque_V2SI_type_node,
12396 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12400 def_builtin (d->mask, d->name, type, d->code);
12405 rs6000_init_libfuncs (void)
12407 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12408 && !TARGET_POWER2 && !TARGET_POWERPC)
12410 /* AIX library routines for float->int conversion. */
12411 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12412 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12413 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12414 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12417 if (!TARGET_IEEEQUAD)
12418 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12419 if (!TARGET_XL_COMPAT)
12421 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12422 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12423 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12424 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12426 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12428 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12429 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12430 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12431 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12432 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12433 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12434 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12436 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12437 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12438 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12439 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12440 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12441 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12442 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12443 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12446 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12447 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12451 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12452 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12453 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12454 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12458 /* 32-bit SVR4 quad floating point routines. */
12460 set_optab_libfunc (add_optab, TFmode, "_q_add");
12461 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12462 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12463 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12464 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12465 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12466 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12468 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12469 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12470 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12471 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12472 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12473 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12475 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12476 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12477 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12478 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12479 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12480 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12481 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12482 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12487 /* Expand a block clear operation, and return 1 if successful. Return 0
12488 if we should let the compiler generate normal code.
12490 operands[0] is the destination
12491 operands[1] is the length
12492 operands[3] is the alignment */
12495 expand_block_clear (rtx operands[])
12497 rtx orig_dest = operands[0];
12498 rtx bytes_rtx = operands[1];
12499 rtx align_rtx = operands[3];
12500 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12501 HOST_WIDE_INT align;
12502 HOST_WIDE_INT bytes;
12507 /* If this is not a fixed size move, just call memcpy */
12511 /* This must be a fixed size alignment */
12512 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12513 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12515 /* Anything to clear? */
12516 bytes = INTVAL (bytes_rtx);
12520 /* Use the builtin memset after a point, to avoid huge code bloat.
12521 When optimize_size, avoid any significant code bloat; calling
12522 memset is about 4 instructions, so allow for one instruction to
12523 load zero and three to do clearing. */
12524 if (TARGET_ALTIVEC && align >= 128)
12526 else if (TARGET_POWERPC64 && align >= 32)
12528 else if (TARGET_SPE && align >= 64)
12533 if (optimize_size && bytes > 3 * clear_step)
12535 if (! optimize_size && bytes > 8 * clear_step)
12538 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12540 enum machine_mode mode = BLKmode;
12543 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12548 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12553 else if (bytes >= 8 && TARGET_POWERPC64
12554 /* 64-bit loads and stores require word-aligned
12556 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12561 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12562 { /* move 4 bytes */
12566 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12567 { /* move 2 bytes */
12571 else /* move 1 byte at a time */
12577 dest = adjust_address (orig_dest, mode, offset);
12579 emit_move_insn (dest, CONST0_RTX (mode));
12586 /* Expand a block move operation, and return 1 if successful. Return 0
12587 if we should let the compiler generate normal code.
12589 operands[0] is the destination
12590 operands[1] is the source
12591 operands[2] is the length
12592 operands[3] is the alignment */
12594 #define MAX_MOVE_REG 4
12597 expand_block_move (rtx operands[])
12599 rtx orig_dest = operands[0];
12600 rtx orig_src = operands[1];
12601 rtx bytes_rtx = operands[2];
12602 rtx align_rtx = operands[3];
12603 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12608 rtx stores[MAX_MOVE_REG];
12611 /* If this is not a fixed size move, just call memcpy */
12615 /* This must be a fixed size alignment */
12616 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12617 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12619 /* Anything to move? */
12620 bytes = INTVAL (bytes_rtx);
12624 /* store_one_arg depends on expand_block_move to handle at least the size of
12625 reg_parm_stack_space. */
12626 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12629 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12632 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12633 rtx (*mov) (rtx, rtx);
12635 enum machine_mode mode = BLKmode;
12638 /* Altivec first, since it will be faster than a string move
12639 when it applies, and usually not significantly larger. */
12640 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12644 gen_func.mov = gen_movv4si;
12646 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12650 gen_func.mov = gen_movv2si;
12652 else if (TARGET_STRING
12653 && bytes > 24 /* move up to 32 bytes at a time */
12659 && ! fixed_regs[10]
12660 && ! fixed_regs[11]
12661 && ! fixed_regs[12])
12663 move_bytes = (bytes > 32) ? 32 : bytes;
12664 gen_func.movmemsi = gen_movmemsi_8reg;
12666 else if (TARGET_STRING
12667 && bytes > 16 /* move up to 24 bytes at a time */
12673 && ! fixed_regs[10])
12675 move_bytes = (bytes > 24) ? 24 : bytes;
12676 gen_func.movmemsi = gen_movmemsi_6reg;
12678 else if (TARGET_STRING
12679 && bytes > 8 /* move up to 16 bytes at a time */
12683 && ! fixed_regs[8])
12685 move_bytes = (bytes > 16) ? 16 : bytes;
12686 gen_func.movmemsi = gen_movmemsi_4reg;
12688 else if (bytes >= 8 && TARGET_POWERPC64
12689 /* 64-bit loads and stores require word-aligned
12691 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12695 gen_func.mov = gen_movdi;
12697 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12698 { /* move up to 8 bytes at a time */
12699 move_bytes = (bytes > 8) ? 8 : bytes;
12700 gen_func.movmemsi = gen_movmemsi_2reg;
12702 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12703 { /* move 4 bytes */
12706 gen_func.mov = gen_movsi;
12708 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12709 { /* move 2 bytes */
12712 gen_func.mov = gen_movhi;
12714 else if (TARGET_STRING && bytes > 1)
12715 { /* move up to 4 bytes at a time */
12716 move_bytes = (bytes > 4) ? 4 : bytes;
12717 gen_func.movmemsi = gen_movmemsi_1reg;
12719 else /* move 1 byte at a time */
12723 gen_func.mov = gen_movqi;
12726 src = adjust_address (orig_src, mode, offset);
12727 dest = adjust_address (orig_dest, mode, offset);
12729 if (mode != BLKmode)
12731 rtx tmp_reg = gen_reg_rtx (mode);
12733 emit_insn ((*gen_func.mov) (tmp_reg, src));
12734 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12737 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12740 for (i = 0; i < num_reg; i++)
12741 emit_insn (stores[i]);
12745 if (mode == BLKmode)
12747 /* Move the address into scratch registers. The movmemsi
12748 patterns require zero offset. */
12749 if (!REG_P (XEXP (src, 0)))
12751 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12752 src = replace_equiv_address (src, src_reg);
12754 set_mem_size (src, GEN_INT (move_bytes));
12756 if (!REG_P (XEXP (dest, 0)))
12758 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12759 dest = replace_equiv_address (dest, dest_reg);
12761 set_mem_size (dest, GEN_INT (move_bytes));
12763 emit_insn ((*gen_func.movmemsi) (dest, src,
12764 GEN_INT (move_bytes & 31),
12773 /* Return a string to perform a load_multiple operation.
12774 operands[0] is the vector.
12775 operands[1] is the source address.
12776 operands[2] is the first destination register. */
12779 rs6000_output_load_multiple (rtx operands[3])
12781 /* We have to handle the case where the pseudo used to contain the address
12782 is assigned to one of the output registers. */
12784 int words = XVECLEN (operands[0], 0);
12787 if (XVECLEN (operands[0], 0) == 1)
12788 return "{l|lwz} %2,0(%1)";
12790 for (i = 0; i < words; i++)
12791 if (refers_to_regno_p (REGNO (operands[2]) + i,
12792 REGNO (operands[2]) + i + 1, operands[1], 0))
12796 xop[0] = GEN_INT (4 * (words-1));
12797 xop[1] = operands[1];
12798 xop[2] = operands[2];
12799 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12804 xop[0] = GEN_INT (4 * (words-1));
12805 xop[1] = operands[1];
12806 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12807 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);
12812 for (j = 0; j < words; j++)
12815 xop[0] = GEN_INT (j * 4);
12816 xop[1] = operands[1];
12817 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12818 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12820 xop[0] = GEN_INT (i * 4);
12821 xop[1] = operands[1];
12822 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12827 return "{lsi|lswi} %2,%1,%N0";
12831 /* A validation routine: say whether CODE, a condition code, and MODE
12832 match. The other alternatives either don't make sense or should
12833 never be generated. */
12836 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12838 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12839 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12840 && GET_MODE_CLASS (mode) == MODE_CC);
12842 /* These don't make sense. */
12843 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12844 || mode != CCUNSmode);
12846 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12847 || mode == CCUNSmode);
12849 gcc_assert (mode == CCFPmode
12850 || (code != ORDERED && code != UNORDERED
12851 && code != UNEQ && code != LTGT
12852 && code != UNGT && code != UNLT
12853 && code != UNGE && code != UNLE));
12855 /* These should never be generated except for
12856 flag_finite_math_only. */
12857 gcc_assert (mode != CCFPmode
12858 || flag_finite_math_only
12859 || (code != LE && code != GE
12860 && code != UNEQ && code != LTGT
12861 && code != UNGT && code != UNLT));
12863 /* These are invalid; the information is not there. */
12864 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12868 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12869 mask required to convert the result of a rotate insn into a shift
12870 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12873 includes_lshift_p (rtx shiftop, rtx andop)
12875 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12877 shift_mask <<= INTVAL (shiftop);
12879 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12882 /* Similar, but for right shift. */
12885 includes_rshift_p (rtx shiftop, rtx andop)
12887 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12889 shift_mask >>= INTVAL (shiftop);
12891 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12894 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12895 to perform a left shift. It must have exactly SHIFTOP least
12896 significant 0's, then one or more 1's, then zero or more 0's. */
12899 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12901 if (GET_CODE (andop) == CONST_INT)
12903 HOST_WIDE_INT c, lsb, shift_mask;
12905 c = INTVAL (andop);
12906 if (c == 0 || c == ~0)
12910 shift_mask <<= INTVAL (shiftop);
12912 /* Find the least significant one bit. */
12915 /* It must coincide with the LSB of the shift mask. */
12916 if (-lsb != shift_mask)
12919 /* Invert to look for the next transition (if any). */
12922 /* Remove the low group of ones (originally low group of zeros). */
12925 /* Again find the lsb, and check we have all 1's above. */
12929 else if (GET_CODE (andop) == CONST_DOUBLE
12930 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12932 HOST_WIDE_INT low, high, lsb;
12933 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12935 low = CONST_DOUBLE_LOW (andop);
12936 if (HOST_BITS_PER_WIDE_INT < 64)
12937 high = CONST_DOUBLE_HIGH (andop);
12939 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12940 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12943 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12945 shift_mask_high = ~0;
12946 if (INTVAL (shiftop) > 32)
12947 shift_mask_high <<= INTVAL (shiftop) - 32;
12949 lsb = high & -high;
12951 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12957 lsb = high & -high;
12958 return high == -lsb;
12961 shift_mask_low = ~0;
12962 shift_mask_low <<= INTVAL (shiftop);
12966 if (-lsb != shift_mask_low)
12969 if (HOST_BITS_PER_WIDE_INT < 64)
12974 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12976 lsb = high & -high;
12977 return high == -lsb;
12981 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12987 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12988 to perform a left shift. It must have SHIFTOP or more least
12989 significant 0's, with the remainder of the word 1's. */
12992 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12994 if (GET_CODE (andop) == CONST_INT)
12996 HOST_WIDE_INT c, lsb, shift_mask;
12999 shift_mask <<= INTVAL (shiftop);
13000 c = INTVAL (andop);
13002 /* Find the least significant one bit. */
13005 /* It must be covered by the shift mask.
13006 This test also rejects c == 0. */
13007 if ((lsb & shift_mask) == 0)
13010 /* Check we have all 1's above the transition, and reject all 1's. */
13011 return c == -lsb && lsb != 1;
13013 else if (GET_CODE (andop) == CONST_DOUBLE
13014 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13016 HOST_WIDE_INT low, lsb, shift_mask_low;
13018 low = CONST_DOUBLE_LOW (andop);
13020 if (HOST_BITS_PER_WIDE_INT < 64)
13022 HOST_WIDE_INT high, shift_mask_high;
13024 high = CONST_DOUBLE_HIGH (andop);
13028 shift_mask_high = ~0;
13029 if (INTVAL (shiftop) > 32)
13030 shift_mask_high <<= INTVAL (shiftop) - 32;
13032 lsb = high & -high;
13034 if ((lsb & shift_mask_high) == 0)
13037 return high == -lsb;
13043 shift_mask_low = ~0;
13044 shift_mask_low <<= INTVAL (shiftop);
13048 if ((lsb & shift_mask_low) == 0)
13051 return low == -lsb && lsb != 1;
13057 /* Return 1 if operands will generate a valid arguments to rlwimi
13058 instruction for insert with right shift in 64-bit mode. The mask may
13059 not start on the first bit or stop on the last bit because wrap-around
13060 effects of instruction do not correspond to semantics of RTL insn. */
13063 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13065 if (INTVAL (startop) > 32
13066 && INTVAL (startop) < 64
13067 && INTVAL (sizeop) > 1
13068 && INTVAL (sizeop) + INTVAL (startop) < 64
13069 && INTVAL (shiftop) > 0
13070 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13071 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13077 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13078 for lfq and stfq insns iff the registers are hard registers. */
13081 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13083 /* We might have been passed a SUBREG. */
13084 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13087 /* We might have been passed non floating point registers. */
13088 if (!FP_REGNO_P (REGNO (reg1))
13089 || !FP_REGNO_P (REGNO (reg2)))
13092 return (REGNO (reg1) == REGNO (reg2) - 1);
13095 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13096 addr1 and addr2 must be in consecutive memory locations
13097 (addr2 == addr1 + 8). */
13100 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13103 unsigned int reg1, reg2;
13104 int offset1, offset2;
13106 /* The mems cannot be volatile. */
13107 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13110 addr1 = XEXP (mem1, 0);
13111 addr2 = XEXP (mem2, 0);
13113 /* Extract an offset (if used) from the first addr. */
13114 if (GET_CODE (addr1) == PLUS)
13116 /* If not a REG, return zero. */
13117 if (GET_CODE (XEXP (addr1, 0)) != REG)
13121 reg1 = REGNO (XEXP (addr1, 0));
13122 /* The offset must be constant! */
13123 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13125 offset1 = INTVAL (XEXP (addr1, 1));
13128 else if (GET_CODE (addr1) != REG)
13132 reg1 = REGNO (addr1);
13133 /* This was a simple (mem (reg)) expression. Offset is 0. */
13137 /* And now for the second addr. */
13138 if (GET_CODE (addr2) == PLUS)
13140 /* If not a REG, return zero. */
13141 if (GET_CODE (XEXP (addr2, 0)) != REG)
13145 reg2 = REGNO (XEXP (addr2, 0));
13146 /* The offset must be constant. */
13147 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13149 offset2 = INTVAL (XEXP (addr2, 1));
13152 else if (GET_CODE (addr2) != REG)
13156 reg2 = REGNO (addr2);
13157 /* This was a simple (mem (reg)) expression. Offset is 0. */
13161 /* Both of these must have the same base register. */
13165 /* The offset for the second addr must be 8 more than the first addr. */
13166 if (offset2 != offset1 + 8)
13169 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13176 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13178 static bool eliminated = false;
13181 if (mode != SDmode)
13182 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13185 rtx mem = cfun->machine->sdmode_stack_slot;
13186 gcc_assert (mem != NULL_RTX);
13190 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13191 cfun->machine->sdmode_stack_slot = mem;
13197 if (TARGET_DEBUG_ADDR)
13199 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13200 GET_MODE_NAME (mode));
13202 fprintf (stderr, "\tNULL_RTX\n");
13211 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13213 /* Don't walk into types. */
13214 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13216 *walk_subtrees = 0;
13220 switch (TREE_CODE (*tp))
13229 case ALIGN_INDIRECT_REF:
13230 case MISALIGNED_INDIRECT_REF:
13231 case VIEW_CONVERT_EXPR:
13232 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13242 enum reload_reg_type {
13244 VECTOR_REGISTER_TYPE,
13245 OTHER_REGISTER_TYPE
13248 static enum reload_reg_type
13249 rs6000_reload_register_type (enum reg_class rclass)
13255 return GPR_REGISTER_TYPE;
13260 return VECTOR_REGISTER_TYPE;
13263 return OTHER_REGISTER_TYPE;
13267 /* Inform reload about cases where moving X with a mode MODE to a register in
13268 RCLASS requires an extra scratch or immediate register. Return the class
13269 needed for the immediate register.
13271 For VSX and Altivec, we may need a register to convert sp+offset into
13274 static enum reg_class
13275 rs6000_secondary_reload (bool in_p,
13277 enum reg_class rclass,
13278 enum machine_mode mode,
13279 secondary_reload_info *sri)
13281 enum reg_class ret = ALL_REGS;
13282 enum insn_code icode;
13283 bool default_p = false;
13285 sri->icode = CODE_FOR_nothing;
13287 /* Convert vector loads and stores into gprs to use an additional base
13289 icode = rs6000_vector_reload[mode][in_p != false];
13290 if (icode != CODE_FOR_nothing)
13293 sri->icode = CODE_FOR_nothing;
13294 sri->extra_cost = 0;
13296 if (GET_CODE (x) == MEM)
13298 rtx addr = XEXP (x, 0);
13300 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13301 an extra register in that case, but it would need an extra
13302 register if the addressing is reg+reg or (reg+reg)&(-16). */
13303 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13305 if (!legitimate_indirect_address_p (addr, false)
13306 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13308 sri->icode = icode;
13309 /* account for splitting the loads, and converting the
13310 address from reg+reg to reg. */
13311 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13312 + ((GET_CODE (addr) == AND) ? 1 : 0));
13315 /* Loads to and stores from vector registers can only do reg+reg
13316 addressing. Altivec registers can also do (reg+reg)&(-16). */
13317 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13318 || rclass == FLOAT_REGS || rclass == NO_REGS)
13320 if (!VECTOR_MEM_ALTIVEC_P (mode)
13321 && GET_CODE (addr) == AND
13322 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13323 && INTVAL (XEXP (addr, 1)) == -16
13324 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13325 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13327 sri->icode = icode;
13328 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13331 else if (!legitimate_indirect_address_p (addr, false)
13332 && (rclass == NO_REGS
13333 || !legitimate_indexed_address_p (addr, false)))
13335 sri->icode = icode;
13336 sri->extra_cost = 1;
13339 icode = CODE_FOR_nothing;
13341 /* Any other loads, including to pseudo registers which haven't been
13342 assigned to a register yet, default to require a scratch
13346 sri->icode = icode;
13347 sri->extra_cost = 2;
13350 else if (REG_P (x))
13352 int regno = true_regnum (x);
13354 icode = CODE_FOR_nothing;
13355 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13359 enum reg_class xclass = REGNO_REG_CLASS (regno);
13360 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13361 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13363 /* If memory is needed, use default_secondary_reload to create the
13365 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13378 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13380 gcc_assert (ret != ALL_REGS);
13382 if (TARGET_DEBUG_ADDR)
13385 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13387 reg_class_names[ret],
13388 in_p ? "true" : "false",
13389 reg_class_names[rclass],
13390 GET_MODE_NAME (mode));
13393 fprintf (stderr, ", default secondary reload");
13395 if (sri->icode != CODE_FOR_nothing)
13396 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13397 insn_data[sri->icode].name, sri->extra_cost);
13399 fprintf (stderr, "\n");
13407 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13408 to SP+reg addressing. */
13411 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13413 int regno = true_regnum (reg);
13414 enum machine_mode mode = GET_MODE (reg);
13415 enum reg_class rclass;
13417 rtx and_op2 = NULL_RTX;
13420 rtx scratch_or_premodify = scratch;
13424 if (TARGET_DEBUG_ADDR)
13426 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13427 store_p ? "store" : "load");
13428 fprintf (stderr, "reg:\n");
13430 fprintf (stderr, "mem:\n");
13432 fprintf (stderr, "scratch:\n");
13433 debug_rtx (scratch);
13436 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13437 gcc_assert (GET_CODE (mem) == MEM);
13438 rclass = REGNO_REG_CLASS (regno);
13439 addr = XEXP (mem, 0);
13443 /* GPRs can handle reg + small constant, all other addresses need to use
13444 the scratch register. */
13447 if (GET_CODE (addr) == AND)
13449 and_op2 = XEXP (addr, 1);
13450 addr = XEXP (addr, 0);
13453 if (GET_CODE (addr) == PRE_MODIFY)
13455 scratch_or_premodify = XEXP (addr, 0);
13456 gcc_assert (REG_P (scratch_or_premodify));
13457 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13458 addr = XEXP (addr, 1);
13461 if (GET_CODE (addr) == PLUS
13462 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13463 || and_op2 != NULL_RTX))
13465 addr_op1 = XEXP (addr, 0);
13466 addr_op2 = XEXP (addr, 1);
13467 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13469 if (!REG_P (addr_op2)
13470 && (GET_CODE (addr_op2) != CONST_INT
13471 || !satisfies_constraint_I (addr_op2)))
13473 if (TARGET_DEBUG_ADDR)
13476 "\nMove plus addr to register %s, mode = %s: ",
13477 rs6000_reg_names[REGNO (scratch)],
13478 GET_MODE_NAME (mode));
13479 debug_rtx (addr_op2);
13481 rs6000_emit_move (scratch, addr_op2, Pmode);
13482 addr_op2 = scratch;
13485 emit_insn (gen_rtx_SET (VOIDmode,
13486 scratch_or_premodify,
13487 gen_rtx_PLUS (Pmode,
13491 addr = scratch_or_premodify;
13492 scratch_or_premodify = scratch;
13494 else if (!legitimate_indirect_address_p (addr, false)
13495 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13497 if (TARGET_DEBUG_ADDR)
13499 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13500 rs6000_reg_names[REGNO (scratch_or_premodify)],
13501 GET_MODE_NAME (mode));
13504 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13505 addr = scratch_or_premodify;
13506 scratch_or_premodify = scratch;
13510 /* Float/Altivec registers can only handle reg+reg addressing. Move
13511 other addresses into a scratch register. */
13516 /* With float regs, we need to handle the AND ourselves, since we can't
13517 use the Altivec instruction with an implicit AND -16. Allow scalar
13518 loads to float registers to use reg+offset even if VSX. */
13519 if (GET_CODE (addr) == AND
13520 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13521 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13522 || INTVAL (XEXP (addr, 1)) != -16
13523 || !VECTOR_MEM_ALTIVEC_P (mode)))
13525 and_op2 = XEXP (addr, 1);
13526 addr = XEXP (addr, 0);
13529 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13530 as the address later. */
13531 if (GET_CODE (addr) == PRE_MODIFY
13532 && (!VECTOR_MEM_VSX_P (mode)
13533 || and_op2 != NULL_RTX
13534 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13536 scratch_or_premodify = XEXP (addr, 0);
13537 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13539 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13540 addr = XEXP (addr, 1);
13543 if (legitimate_indirect_address_p (addr, false) /* reg */
13544 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13545 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13546 || (GET_CODE (addr) == AND /* Altivec memory */
13547 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13548 && INTVAL (XEXP (addr, 1)) == -16
13549 && VECTOR_MEM_ALTIVEC_P (mode))
13550 || (rclass == FLOAT_REGS /* legacy float mem */
13551 && GET_MODE_SIZE (mode) == 8
13552 && and_op2 == NULL_RTX
13553 && scratch_or_premodify == scratch
13554 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13557 else if (GET_CODE (addr) == PLUS)
13559 addr_op1 = XEXP (addr, 0);
13560 addr_op2 = XEXP (addr, 1);
13561 gcc_assert (REG_P (addr_op1));
13563 if (TARGET_DEBUG_ADDR)
13565 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13566 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13567 debug_rtx (addr_op2);
13569 rs6000_emit_move (scratch, addr_op2, Pmode);
13570 emit_insn (gen_rtx_SET (VOIDmode,
13571 scratch_or_premodify,
13572 gen_rtx_PLUS (Pmode,
13575 addr = scratch_or_premodify;
13576 scratch_or_premodify = scratch;
13579 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13580 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13582 if (TARGET_DEBUG_ADDR)
13584 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13585 rs6000_reg_names[REGNO (scratch_or_premodify)],
13586 GET_MODE_NAME (mode));
13590 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13591 addr = scratch_or_premodify;
13592 scratch_or_premodify = scratch;
13596 gcc_unreachable ();
13601 gcc_unreachable ();
13604 /* If the original address involved a pre-modify that we couldn't use the VSX
13605 memory instruction with update, and we haven't taken care of already,
13606 store the address in the pre-modify register and use that as the
13608 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13610 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13611 addr = scratch_or_premodify;
13614 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13615 memory instruction, recreate the AND now, including the clobber which is
13616 generated by the general ANDSI3/ANDDI3 patterns for the
13617 andi. instruction. */
13618 if (and_op2 != NULL_RTX)
13620 if (! legitimate_indirect_address_p (addr, false))
13622 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13626 if (TARGET_DEBUG_ADDR)
13628 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13629 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13630 debug_rtx (and_op2);
13633 and_rtx = gen_rtx_SET (VOIDmode,
13635 gen_rtx_AND (Pmode,
13639 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13640 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13641 gen_rtvec (2, and_rtx, cc_clobber)));
13645 /* Adjust the address if it changed. */
13646 if (addr != XEXP (mem, 0))
13648 mem = change_address (mem, mode, addr);
13649 if (TARGET_DEBUG_ADDR)
13650 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13653 /* Now create the move. */
13655 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13657 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13662 /* Target hook to return the cover classes for Integrated Register Allocator.
13663 Cover classes is a set of non-intersected register classes covering all hard
13664 registers used for register allocation purpose. Any move between two
13665 registers of a cover class should be cheaper than load or store of the
13666 registers. The value is array of register classes with LIM_REG_CLASSES used
13669 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13670 account for the Altivec and Floating registers being subsets of the VSX
13671 register set under VSX, but distinct register sets on pre-VSX machines. */
13673 static const enum reg_class *
13674 rs6000_ira_cover_classes (void)
13676 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13677 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13679 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13682 /* Allocate a 64-bit stack slot to be used for copying SDmode
13683 values through if this function has any SDmode references. */
13686 rs6000_alloc_sdmode_stack_slot (void)
13690 gimple_stmt_iterator gsi;
13692 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13695 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13697 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13700 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13701 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13707 /* Check for any SDmode parameters of the function. */
13708 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13710 if (TREE_TYPE (t) == error_mark_node)
13713 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13714 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13716 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13717 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13725 rs6000_instantiate_decls (void)
13727 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13728 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13731 /* Given an rtx X being reloaded into a reg required to be
13732 in class CLASS, return the class of reg to actually use.
13733 In general this is just CLASS; but on some machines
13734 in some cases it is preferable to use a more restrictive class.
13736 On the RS/6000, we have to return NO_REGS when we want to reload a
13737 floating-point CONST_DOUBLE to force it to be copied to memory.
13739 We also don't want to reload integer values into floating-point
13740 registers if we can at all help it. In fact, this can
13741 cause reload to die, if it tries to generate a reload of CTR
13742 into a FP register and discovers it doesn't have the memory location
13745 ??? Would it be a good idea to have reload do the converse, that is
13746 try to reload floating modes into FP registers if possible?
13749 static enum reg_class
13750 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13752 enum machine_mode mode = GET_MODE (x);
13754 if (VECTOR_UNIT_VSX_P (mode)
13755 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13758 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13759 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13760 && easy_vector_constant (x, mode))
13761 return ALTIVEC_REGS;
13763 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13766 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13767 return GENERAL_REGS;
13769 /* For VSX, prefer the traditional registers for DF if the address is of the
13770 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13771 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13773 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13775 if (mode == DFmode && GET_CODE (x) == MEM)
13777 rtx addr = XEXP (x, 0);
13779 if (legitimate_indirect_address_p (addr, false)) /* reg */
13782 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13785 if (GET_CODE (addr) == PRE_MODIFY
13786 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13792 if (VECTOR_UNIT_ALTIVEC_P (mode))
13793 return ALTIVEC_REGS;
13801 /* Debug version of rs6000_preferred_reload_class. */
13802 static enum reg_class
13803 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13805 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13808 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13810 reg_class_names[ret], reg_class_names[rclass],
13811 GET_MODE_NAME (GET_MODE (x)));
13817 /* If we are copying between FP or AltiVec registers and anything else, we need
13818 a memory location. The exception is when we are targeting ppc64 and the
13819 move to/from fpr to gpr instructions are available. Also, under VSX, you
13820 can copy vector registers from the FP register set to the Altivec register
13821 set and vice versa. */
13824 rs6000_secondary_memory_needed (enum reg_class class1,
13825 enum reg_class class2,
13826 enum machine_mode mode)
13828 if (class1 == class2)
13831 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13832 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13833 between these classes. But we need memory for other things that can go in
13834 FLOAT_REGS like SFmode. */
13836 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13837 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13838 || class1 == FLOAT_REGS))
13839 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13840 && class2 != FLOAT_REGS);
13842 if (class1 == VSX_REGS || class2 == VSX_REGS)
13845 if (class1 == FLOAT_REGS
13846 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13847 || ((mode != DFmode)
13848 && (mode != DDmode)
13849 && (mode != DImode))))
13852 if (class2 == FLOAT_REGS
13853 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13854 || ((mode != DFmode)
13855 && (mode != DDmode)
13856 && (mode != DImode))))
13859 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13865 /* Debug version of rs6000_secondary_memory_needed. */
13867 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13868 enum reg_class class2,
13869 enum machine_mode mode)
13871 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13874 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13875 "class2 = %s, mode = %s\n",
13876 ret ? "true" : "false", reg_class_names[class1],
13877 reg_class_names[class2], GET_MODE_NAME (mode));
13882 /* Return the register class of a scratch register needed to copy IN into
13883 or out of a register in RCLASS in MODE. If it can be done directly,
13884 NO_REGS is returned. */
13886 static enum reg_class
13887 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13892 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13894 && MACHOPIC_INDIRECT
13898 /* We cannot copy a symbolic operand directly into anything
13899 other than BASE_REGS for TARGET_ELF. So indicate that a
13900 register from BASE_REGS is needed as an intermediate
13903 On Darwin, pic addresses require a load from memory, which
13904 needs a base register. */
13905 if (rclass != BASE_REGS
13906 && (GET_CODE (in) == SYMBOL_REF
13907 || GET_CODE (in) == HIGH
13908 || GET_CODE (in) == LABEL_REF
13909 || GET_CODE (in) == CONST))
13913 if (GET_CODE (in) == REG)
13915 regno = REGNO (in);
13916 if (regno >= FIRST_PSEUDO_REGISTER)
13918 regno = true_regnum (in);
13919 if (regno >= FIRST_PSEUDO_REGISTER)
13923 else if (GET_CODE (in) == SUBREG)
13925 regno = true_regnum (in);
13926 if (regno >= FIRST_PSEUDO_REGISTER)
13932 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13934 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13935 || (regno >= 0 && INT_REGNO_P (regno)))
13938 /* Constants, memory, and FP registers can go into FP registers. */
13939 if ((regno == -1 || FP_REGNO_P (regno))
13940 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13941 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13943 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13946 && (regno == -1 || VSX_REGNO_P (regno))
13947 && VSX_REG_CLASS_P (rclass))
13950 /* Memory, and AltiVec registers can go into AltiVec registers. */
13951 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13952 && rclass == ALTIVEC_REGS)
13955 /* We can copy among the CR registers. */
13956 if ((rclass == CR_REGS || rclass == CR0_REGS)
13957 && regno >= 0 && CR_REGNO_P (regno))
13960 /* Otherwise, we need GENERAL_REGS. */
13961 return GENERAL_REGS;
13964 /* Debug version of rs6000_secondary_reload_class. */
13965 static enum reg_class
13966 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13967 enum machine_mode mode, rtx in)
13969 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13971 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13972 "mode = %s, input rtx:\n",
13973 reg_class_names[ret], reg_class_names[rclass],
13974 GET_MODE_NAME (mode));
13980 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13983 rs6000_cannot_change_mode_class (enum machine_mode from,
13984 enum machine_mode to,
13985 enum reg_class rclass)
13987 unsigned from_size = GET_MODE_SIZE (from);
13988 unsigned to_size = GET_MODE_SIZE (to);
13990 if (from_size != to_size)
13992 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13993 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13994 && reg_classes_intersect_p (xclass, rclass));
13997 if (TARGET_E500_DOUBLE
13998 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13999 || (((to) == TFmode) + ((from) == TFmode)) == 1
14000 || (((to) == DDmode) + ((from) == DDmode)) == 1
14001 || (((to) == TDmode) + ((from) == TDmode)) == 1
14002 || (((to) == DImode) + ((from) == DImode)) == 1))
14005 /* Since the VSX register set includes traditional floating point registers
14006 and altivec registers, just check for the size being different instead of
14007 trying to check whether the modes are vector modes. Otherwise it won't
14008 allow say DF and DI to change classes. */
14009 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14010 return (from_size != 8 && from_size != 16);
14012 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14013 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14016 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14017 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14023 /* Debug version of rs6000_cannot_change_mode_class. */
14025 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14026 enum machine_mode to,
14027 enum reg_class rclass)
14029 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14032 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14033 "to = %s, rclass = %s\n",
14034 ret ? "true" : "false",
14035 GET_MODE_NAME (from), GET_MODE_NAME (to),
14036 reg_class_names[rclass]);
14041 /* Given a comparison operation, return the bit number in CCR to test. We
14042 know this is a valid comparison.
14044 SCC_P is 1 if this is for an scc. That means that %D will have been
14045 used instead of %C, so the bits will be in different places.
14047 Return -1 if OP isn't a valid comparison for some reason. */
14050 ccr_bit (rtx op, int scc_p)
14052 enum rtx_code code = GET_CODE (op);
14053 enum machine_mode cc_mode;
14058 if (!COMPARISON_P (op))
14061 reg = XEXP (op, 0);
14063 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14065 cc_mode = GET_MODE (reg);
14066 cc_regnum = REGNO (reg);
14067 base_bit = 4 * (cc_regnum - CR0_REGNO);
14069 validate_condition_mode (code, cc_mode);
14071 /* When generating a sCOND operation, only positive conditions are
14074 || code == EQ || code == GT || code == LT || code == UNORDERED
14075 || code == GTU || code == LTU);
14080 return scc_p ? base_bit + 3 : base_bit + 2;
14082 return base_bit + 2;
14083 case GT: case GTU: case UNLE:
14084 return base_bit + 1;
14085 case LT: case LTU: case UNGE:
14087 case ORDERED: case UNORDERED:
14088 return base_bit + 3;
14091 /* If scc, we will have done a cror to put the bit in the
14092 unordered position. So test that bit. For integer, this is ! LT
14093 unless this is an scc insn. */
14094 return scc_p ? base_bit + 3 : base_bit;
14097 return scc_p ? base_bit + 3 : base_bit + 1;
14100 gcc_unreachable ();
14104 /* Return the GOT register. */
14107 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14109 /* The second flow pass currently (June 1999) can't update
14110 regs_ever_live without disturbing other parts of the compiler, so
14111 update it here to make the prolog/epilogue code happy. */
14112 if (!can_create_pseudo_p ()
14113 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14114 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14116 crtl->uses_pic_offset_table = 1;
14118 return pic_offset_table_rtx;
14121 /* Function to init struct machine_function.
14122 This will be called, via a pointer variable,
14123 from push_function_context. */
14125 static struct machine_function *
14126 rs6000_init_machine_status (void)
14128 return GGC_CNEW (machine_function);
14131 /* These macros test for integers and extract the low-order bits. */
14133 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14134 && GET_MODE (X) == VOIDmode)
14136 #define INT_LOWPART(X) \
14137 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14140 extract_MB (rtx op)
14143 unsigned long val = INT_LOWPART (op);
14145 /* If the high bit is zero, the value is the first 1 bit we find
14147 if ((val & 0x80000000) == 0)
14149 gcc_assert (val & 0xffffffff);
14152 while (((val <<= 1) & 0x80000000) == 0)
14157 /* If the high bit is set and the low bit is not, or the mask is all
14158 1's, the value is zero. */
14159 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14162 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14165 while (((val >>= 1) & 1) != 0)
14172 extract_ME (rtx op)
14175 unsigned long val = INT_LOWPART (op);
14177 /* If the low bit is zero, the value is the first 1 bit we find from
14179 if ((val & 1) == 0)
14181 gcc_assert (val & 0xffffffff);
14184 while (((val >>= 1) & 1) == 0)
14190 /* If the low bit is set and the high bit is not, or the mask is all
14191 1's, the value is 31. */
14192 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14195 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14198 while (((val <<= 1) & 0x80000000) != 0)
14204 /* Locate some local-dynamic symbol still in use by this function
14205 so that we can print its name in some tls_ld pattern. */
14207 static const char *
14208 rs6000_get_some_local_dynamic_name (void)
14212 if (cfun->machine->some_ld_name)
14213 return cfun->machine->some_ld_name;
14215 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14217 && for_each_rtx (&PATTERN (insn),
14218 rs6000_get_some_local_dynamic_name_1, 0))
14219 return cfun->machine->some_ld_name;
14221 gcc_unreachable ();
14224 /* Helper function for rs6000_get_some_local_dynamic_name. */
14227 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14231 if (GET_CODE (x) == SYMBOL_REF)
14233 const char *str = XSTR (x, 0);
14234 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14236 cfun->machine->some_ld_name = str;
14244 /* Write out a function code label. */
14247 rs6000_output_function_entry (FILE *file, const char *fname)
14249 if (fname[0] != '.')
14251 switch (DEFAULT_ABI)
14254 gcc_unreachable ();
14260 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14269 RS6000_OUTPUT_BASENAME (file, fname);
14271 assemble_name (file, fname);
14274 /* Print an operand. Recognize special options, documented below. */
14277 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14278 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14280 #define SMALL_DATA_RELOC "sda21"
14281 #define SMALL_DATA_REG 0
14285 print_operand (FILE *file, rtx x, int code)
14289 unsigned HOST_WIDE_INT uval;
14294 /* Write out an instruction after the call which may be replaced
14295 with glue code by the loader. This depends on the AIX version. */
14296 asm_fprintf (file, RS6000_CALL_GLUE);
14299 /* %a is output_address. */
14302 /* If X is a constant integer whose low-order 5 bits are zero,
14303 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14304 in the AIX assembler where "sri" with a zero shift count
14305 writes a trash instruction. */
14306 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14313 /* If constant, low-order 16 bits of constant, unsigned.
14314 Otherwise, write normally. */
14316 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14318 print_operand (file, x, 0);
14322 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14323 for 64-bit mask direction. */
14324 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14327 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14331 /* X is a CR register. Print the number of the GT bit of the CR. */
14332 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14333 output_operand_lossage ("invalid %%c value");
14335 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14339 /* Like 'J' but get to the GT bit only. */
14340 gcc_assert (GET_CODE (x) == REG);
14342 /* Bit 1 is GT bit. */
14343 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14345 /* Add one for shift count in rlinm for scc. */
14346 fprintf (file, "%d", i + 1);
14350 /* X is a CR register. Print the number of the EQ bit of the CR */
14351 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14352 output_operand_lossage ("invalid %%E value");
14354 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14358 /* X is a CR register. Print the shift count needed to move it
14359 to the high-order four bits. */
14360 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14361 output_operand_lossage ("invalid %%f value");
14363 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14367 /* Similar, but print the count for the rotate in the opposite
14369 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14370 output_operand_lossage ("invalid %%F value");
14372 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14376 /* X is a constant integer. If it is negative, print "m",
14377 otherwise print "z". This is to make an aze or ame insn. */
14378 if (GET_CODE (x) != CONST_INT)
14379 output_operand_lossage ("invalid %%G value");
14380 else if (INTVAL (x) >= 0)
14387 /* If constant, output low-order five bits. Otherwise, write
14390 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14392 print_operand (file, x, 0);
14396 /* If constant, output low-order six bits. Otherwise, write
14399 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14401 print_operand (file, x, 0);
14405 /* Print `i' if this is a constant, else nothing. */
14411 /* Write the bit number in CCR for jump. */
14412 i = ccr_bit (x, 0);
14414 output_operand_lossage ("invalid %%j code");
14416 fprintf (file, "%d", i);
14420 /* Similar, but add one for shift count in rlinm for scc and pass
14421 scc flag to `ccr_bit'. */
14422 i = ccr_bit (x, 1);
14424 output_operand_lossage ("invalid %%J code");
14426 /* If we want bit 31, write a shift count of zero, not 32. */
14427 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14431 /* X must be a constant. Write the 1's complement of the
14434 output_operand_lossage ("invalid %%k value");
14436 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14440 /* X must be a symbolic constant on ELF. Write an
14441 expression suitable for an 'addi' that adds in the low 16
14442 bits of the MEM. */
14443 if (GET_CODE (x) != CONST)
14445 print_operand_address (file, x);
14446 fputs ("@l", file);
14450 if (GET_CODE (XEXP (x, 0)) != PLUS
14451 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14452 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14453 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14454 output_operand_lossage ("invalid %%K value");
14455 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14456 fputs ("@l", file);
14457 /* For GNU as, there must be a non-alphanumeric character
14458 between 'l' and the number. The '-' is added by
14459 print_operand() already. */
14460 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14462 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14466 /* %l is output_asm_label. */
14469 /* Write second word of DImode or DFmode reference. Works on register
14470 or non-indexed memory only. */
14471 if (GET_CODE (x) == REG)
14472 fputs (reg_names[REGNO (x) + 1], file);
14473 else if (GET_CODE (x) == MEM)
14475 /* Handle possible auto-increment. Since it is pre-increment and
14476 we have already done it, we can just use an offset of word. */
14477 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14478 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14479 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14481 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14482 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14485 output_address (XEXP (adjust_address_nv (x, SImode,
14489 if (small_data_operand (x, GET_MODE (x)))
14490 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14491 reg_names[SMALL_DATA_REG]);
14496 /* MB value for a mask operand. */
14497 if (! mask_operand (x, SImode))
14498 output_operand_lossage ("invalid %%m value");
14500 fprintf (file, "%d", extract_MB (x));
14504 /* ME value for a mask operand. */
14505 if (! mask_operand (x, SImode))
14506 output_operand_lossage ("invalid %%M value");
14508 fprintf (file, "%d", extract_ME (x));
14511 /* %n outputs the negative of its operand. */
14514 /* Write the number of elements in the vector times 4. */
14515 if (GET_CODE (x) != PARALLEL)
14516 output_operand_lossage ("invalid %%N value");
14518 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14522 /* Similar, but subtract 1 first. */
14523 if (GET_CODE (x) != PARALLEL)
14524 output_operand_lossage ("invalid %%O value");
14526 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14530 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14532 || INT_LOWPART (x) < 0
14533 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14534 output_operand_lossage ("invalid %%p value");
14536 fprintf (file, "%d", i);
14540 /* The operand must be an indirect memory reference. The result
14541 is the register name. */
14542 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14543 || REGNO (XEXP (x, 0)) >= 32)
14544 output_operand_lossage ("invalid %%P value");
14546 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14550 /* This outputs the logical code corresponding to a boolean
14551 expression. The expression may have one or both operands
14552 negated (if one, only the first one). For condition register
14553 logical operations, it will also treat the negated
14554 CR codes as NOTs, but not handle NOTs of them. */
14556 const char *const *t = 0;
14558 enum rtx_code code = GET_CODE (x);
14559 static const char * const tbl[3][3] = {
14560 { "and", "andc", "nor" },
14561 { "or", "orc", "nand" },
14562 { "xor", "eqv", "xor" } };
14566 else if (code == IOR)
14568 else if (code == XOR)
14571 output_operand_lossage ("invalid %%q value");
14573 if (GET_CODE (XEXP (x, 0)) != NOT)
14577 if (GET_CODE (XEXP (x, 1)) == NOT)
14595 /* X is a CR register. Print the mask for `mtcrf'. */
14596 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14597 output_operand_lossage ("invalid %%R value");
14599 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14603 /* Low 5 bits of 32 - value */
14605 output_operand_lossage ("invalid %%s value");
14607 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14611 /* PowerPC64 mask position. All 0's is excluded.
14612 CONST_INT 32-bit mask is considered sign-extended so any
14613 transition must occur within the CONST_INT, not on the boundary. */
14614 if (! mask64_operand (x, DImode))
14615 output_operand_lossage ("invalid %%S value");
14617 uval = INT_LOWPART (x);
14619 if (uval & 1) /* Clear Left */
14621 #if HOST_BITS_PER_WIDE_INT > 64
14622 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14626 else /* Clear Right */
14629 #if HOST_BITS_PER_WIDE_INT > 64
14630 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14636 gcc_assert (i >= 0);
14637 fprintf (file, "%d", i);
14641 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14642 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14644 /* Bit 3 is OV bit. */
14645 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14647 /* If we want bit 31, write a shift count of zero, not 32. */
14648 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14652 /* Print the symbolic name of a branch target register. */
14653 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14654 && REGNO (x) != CTR_REGNO))
14655 output_operand_lossage ("invalid %%T value");
14656 else if (REGNO (x) == LR_REGNO)
14657 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14659 fputs ("ctr", file);
14663 /* High-order 16 bits of constant for use in unsigned operand. */
14665 output_operand_lossage ("invalid %%u value");
14667 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14668 (INT_LOWPART (x) >> 16) & 0xffff);
14672 /* High-order 16 bits of constant for use in signed operand. */
14674 output_operand_lossage ("invalid %%v value");
14676 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14677 (INT_LOWPART (x) >> 16) & 0xffff);
14681 /* Print `u' if this has an auto-increment or auto-decrement. */
14682 if (GET_CODE (x) == MEM
14683 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14684 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14685 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14690 /* Print the trap code for this operand. */
14691 switch (GET_CODE (x))
14694 fputs ("eq", file); /* 4 */
14697 fputs ("ne", file); /* 24 */
14700 fputs ("lt", file); /* 16 */
14703 fputs ("le", file); /* 20 */
14706 fputs ("gt", file); /* 8 */
14709 fputs ("ge", file); /* 12 */
14712 fputs ("llt", file); /* 2 */
14715 fputs ("lle", file); /* 6 */
14718 fputs ("lgt", file); /* 1 */
14721 fputs ("lge", file); /* 5 */
14724 gcc_unreachable ();
14729 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14732 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14733 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14735 print_operand (file, x, 0);
14739 /* MB value for a PowerPC64 rldic operand. */
14740 val = (GET_CODE (x) == CONST_INT
14741 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14746 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14747 if ((val <<= 1) < 0)
14750 #if HOST_BITS_PER_WIDE_INT == 32
14751 if (GET_CODE (x) == CONST_INT && i >= 0)
14752 i += 32; /* zero-extend high-part was all 0's */
14753 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14755 val = CONST_DOUBLE_LOW (x);
14761 for ( ; i < 64; i++)
14762 if ((val <<= 1) < 0)
14767 fprintf (file, "%d", i + 1);
14771 /* X is a FPR or Altivec register used in a VSX context. */
14772 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14773 output_operand_lossage ("invalid %%x value");
14776 int reg = REGNO (x);
14777 int vsx_reg = (FP_REGNO_P (reg)
14779 : reg - FIRST_ALTIVEC_REGNO + 32);
14781 #ifdef TARGET_REGNAMES
14782 if (TARGET_REGNAMES)
14783 fprintf (file, "%%vs%d", vsx_reg);
14786 fprintf (file, "%d", vsx_reg);
14791 if (GET_CODE (x) == MEM
14792 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14793 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14794 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14799 /* Like 'L', for third word of TImode */
14800 if (GET_CODE (x) == REG)
14801 fputs (reg_names[REGNO (x) + 2], file);
14802 else if (GET_CODE (x) == MEM)
14804 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14805 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14806 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14807 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14808 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14810 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14811 if (small_data_operand (x, GET_MODE (x)))
14812 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14813 reg_names[SMALL_DATA_REG]);
14818 /* X is a SYMBOL_REF. Write out the name preceded by a
14819 period and without any trailing data in brackets. Used for function
14820 names. If we are configured for System V (or the embedded ABI) on
14821 the PowerPC, do not emit the period, since those systems do not use
14822 TOCs and the like. */
14823 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14825 /* Mark the decl as referenced so that cgraph will output the
14827 if (SYMBOL_REF_DECL (x))
14828 mark_decl_referenced (SYMBOL_REF_DECL (x));
14830 /* For macho, check to see if we need a stub. */
14833 const char *name = XSTR (x, 0);
14835 if (MACHOPIC_INDIRECT
14836 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14837 name = machopic_indirection_name (x, /*stub_p=*/true);
14839 assemble_name (file, name);
14841 else if (!DOT_SYMBOLS)
14842 assemble_name (file, XSTR (x, 0));
14844 rs6000_output_function_entry (file, XSTR (x, 0));
14848 /* Like 'L', for last word of TImode. */
14849 if (GET_CODE (x) == REG)
14850 fputs (reg_names[REGNO (x) + 3], file);
14851 else if (GET_CODE (x) == MEM)
14853 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14854 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14855 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14856 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14857 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14859 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14860 if (small_data_operand (x, GET_MODE (x)))
14861 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14862 reg_names[SMALL_DATA_REG]);
14866 /* Print AltiVec or SPE memory operand. */
14871 gcc_assert (GET_CODE (x) == MEM);
14875 /* Ugly hack because %y is overloaded. */
14876 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14877 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14878 || GET_MODE (x) == TFmode
14879 || GET_MODE (x) == TImode))
14881 /* Handle [reg]. */
14882 if (GET_CODE (tmp) == REG)
14884 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14887 /* Handle [reg+UIMM]. */
14888 else if (GET_CODE (tmp) == PLUS &&
14889 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14893 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14895 x = INTVAL (XEXP (tmp, 1));
14896 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14900 /* Fall through. Must be [reg+reg]. */
14902 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14903 && GET_CODE (tmp) == AND
14904 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14905 && INTVAL (XEXP (tmp, 1)) == -16)
14906 tmp = XEXP (tmp, 0);
14907 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14908 && GET_CODE (tmp) == PRE_MODIFY)
14909 tmp = XEXP (tmp, 1);
14910 if (GET_CODE (tmp) == REG)
14911 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14914 if (!GET_CODE (tmp) == PLUS
14915 || !REG_P (XEXP (tmp, 0))
14916 || !REG_P (XEXP (tmp, 1)))
14918 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14922 if (REGNO (XEXP (tmp, 0)) == 0)
14923 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14924 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14926 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14927 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14933 if (GET_CODE (x) == REG)
14934 fprintf (file, "%s", reg_names[REGNO (x)]);
14935 else if (GET_CODE (x) == MEM)
14937 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14938 know the width from the mode. */
14939 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14940 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14941 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14942 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14943 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14944 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14945 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14946 output_address (XEXP (XEXP (x, 0), 1));
14948 output_address (XEXP (x, 0));
14951 output_addr_const (file, x);
14955 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14959 output_operand_lossage ("invalid %%xn code");
14963 /* Print the address of an operand. */
14966 print_operand_address (FILE *file, rtx x)
14968 if (GET_CODE (x) == REG)
14969 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14970 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14971 || GET_CODE (x) == LABEL_REF)
14973 output_addr_const (file, x);
14974 if (small_data_operand (x, GET_MODE (x)))
14975 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14976 reg_names[SMALL_DATA_REG]);
14978 gcc_assert (!TARGET_TOC);
14980 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14982 gcc_assert (REG_P (XEXP (x, 0)));
14983 if (REGNO (XEXP (x, 0)) == 0)
14984 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14985 reg_names[ REGNO (XEXP (x, 0)) ]);
14987 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14988 reg_names[ REGNO (XEXP (x, 1)) ]);
14990 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14991 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14992 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14994 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14995 && CONSTANT_P (XEXP (x, 1)))
14997 output_addr_const (file, XEXP (x, 1));
14998 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15002 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15003 && CONSTANT_P (XEXP (x, 1)))
15005 fprintf (file, "lo16(");
15006 output_addr_const (file, XEXP (x, 1));
15007 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15010 else if (legitimate_constant_pool_address_p (x))
15012 output_addr_const (file, XEXP (x, 1));
15013 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15016 gcc_unreachable ();
15019 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15022 rs6000_output_addr_const_extra (FILE *file, rtx x)
15024 if (GET_CODE (x) == UNSPEC)
15025 switch (XINT (x, 1))
15027 case UNSPEC_TOCREL:
15028 x = XVECEXP (x, 0, 0);
15029 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15030 output_addr_const (file, x);
15031 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15034 assemble_name (file, toc_label_name);
15036 else if (TARGET_ELF)
15037 fputs ("@toc", file);
15041 case UNSPEC_MACHOPIC_OFFSET:
15042 output_addr_const (file, XVECEXP (x, 0, 0));
15044 machopic_output_function_base_name (file);
15051 /* Target hook for assembling integer objects. The PowerPC version has
15052 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15053 is defined. It also needs to handle DI-mode objects on 64-bit
15057 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15059 #ifdef RELOCATABLE_NEEDS_FIXUP
15060 /* Special handling for SI values. */
15061 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15063 static int recurse = 0;
15065 /* For -mrelocatable, we mark all addresses that need to be fixed up
15066 in the .fixup section. */
15067 if (TARGET_RELOCATABLE
15068 && in_section != toc_section
15069 && in_section != text_section
15070 && !unlikely_text_section_p (in_section)
15072 && GET_CODE (x) != CONST_INT
15073 && GET_CODE (x) != CONST_DOUBLE
15079 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15081 ASM_OUTPUT_LABEL (asm_out_file, buf);
15082 fprintf (asm_out_file, "\t.long\t(");
15083 output_addr_const (asm_out_file, x);
15084 fprintf (asm_out_file, ")@fixup\n");
15085 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15086 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15087 fprintf (asm_out_file, "\t.long\t");
15088 assemble_name (asm_out_file, buf);
15089 fprintf (asm_out_file, "\n\t.previous\n");
15093 /* Remove initial .'s to turn a -mcall-aixdesc function
15094 address into the address of the descriptor, not the function
15096 else if (GET_CODE (x) == SYMBOL_REF
15097 && XSTR (x, 0)[0] == '.'
15098 && DEFAULT_ABI == ABI_AIX)
15100 const char *name = XSTR (x, 0);
15101 while (*name == '.')
15104 fprintf (asm_out_file, "\t.long\t%s\n", name);
15108 #endif /* RELOCATABLE_NEEDS_FIXUP */
15109 return default_assemble_integer (x, size, aligned_p);
15112 #ifdef HAVE_GAS_HIDDEN
15113 /* Emit an assembler directive to set symbol visibility for DECL to
15114 VISIBILITY_TYPE. */
15117 rs6000_assemble_visibility (tree decl, int vis)
15119 /* Functions need to have their entry point symbol visibility set as
15120 well as their descriptor symbol visibility. */
15121 if (DEFAULT_ABI == ABI_AIX
15123 && TREE_CODE (decl) == FUNCTION_DECL)
15125 static const char * const visibility_types[] = {
15126 NULL, "internal", "hidden", "protected"
15129 const char *name, *type;
15131 name = ((* targetm.strip_name_encoding)
15132 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15133 type = visibility_types[vis];
15135 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15136 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15139 default_assemble_visibility (decl, vis);
15144 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15146 /* Reversal of FP compares takes care -- an ordered compare
15147 becomes an unordered compare and vice versa. */
15148 if (mode == CCFPmode
15149 && (!flag_finite_math_only
15150 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15151 || code == UNEQ || code == LTGT))
15152 return reverse_condition_maybe_unordered (code);
15154 return reverse_condition (code);
15157 /* Generate a compare for CODE. Return a brand-new rtx that
15158 represents the result of the compare. */
15161 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15163 enum machine_mode comp_mode;
15164 rtx compare_result;
15165 enum rtx_code code = GET_CODE (cmp);
15166 rtx op0 = XEXP (cmp, 0);
15167 rtx op1 = XEXP (cmp, 1);
15169 if (FLOAT_MODE_P (mode))
15170 comp_mode = CCFPmode;
15171 else if (code == GTU || code == LTU
15172 || code == GEU || code == LEU)
15173 comp_mode = CCUNSmode;
15174 else if ((code == EQ || code == NE)
15175 && GET_CODE (op0) == SUBREG
15176 && GET_CODE (op1) == SUBREG
15177 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15178 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15179 /* These are unsigned values, perhaps there will be a later
15180 ordering compare that can be shared with this one.
15181 Unfortunately we cannot detect the signedness of the operands
15182 for non-subregs. */
15183 comp_mode = CCUNSmode;
15185 comp_mode = CCmode;
15187 /* First, the compare. */
15188 compare_result = gen_reg_rtx (comp_mode);
15190 /* E500 FP compare instructions on the GPRs. Yuck! */
15191 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15192 && FLOAT_MODE_P (mode))
15194 rtx cmp, or_result, compare_result2;
15195 enum machine_mode op_mode = GET_MODE (op0);
15197 if (op_mode == VOIDmode)
15198 op_mode = GET_MODE (op1);
15200 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15201 This explains the following mess. */
15205 case EQ: case UNEQ: case NE: case LTGT:
15209 cmp = (flag_finite_math_only && !flag_trapping_math)
15210 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15211 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15215 cmp = (flag_finite_math_only && !flag_trapping_math)
15216 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15217 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15221 cmp = (flag_finite_math_only && !flag_trapping_math)
15222 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15223 : gen_cmptfeq_gpr (compare_result, op0, op1);
15227 gcc_unreachable ();
15231 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15235 cmp = (flag_finite_math_only && !flag_trapping_math)
15236 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15237 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15241 cmp = (flag_finite_math_only && !flag_trapping_math)
15242 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15243 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15247 cmp = (flag_finite_math_only && !flag_trapping_math)
15248 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15249 : gen_cmptfgt_gpr (compare_result, op0, op1);
15253 gcc_unreachable ();
15257 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15261 cmp = (flag_finite_math_only && !flag_trapping_math)
15262 ? gen_tstsflt_gpr (compare_result, op0, op1)
15263 : gen_cmpsflt_gpr (compare_result, op0, op1);
15267 cmp = (flag_finite_math_only && !flag_trapping_math)
15268 ? gen_tstdflt_gpr (compare_result, op0, op1)
15269 : gen_cmpdflt_gpr (compare_result, op0, op1);
15273 cmp = (flag_finite_math_only && !flag_trapping_math)
15274 ? gen_tsttflt_gpr (compare_result, op0, op1)
15275 : gen_cmptflt_gpr (compare_result, op0, op1);
15279 gcc_unreachable ();
15283 gcc_unreachable ();
15286 /* Synthesize LE and GE from LT/GT || EQ. */
15287 if (code == LE || code == GE || code == LEU || code == GEU)
15293 case LE: code = LT; break;
15294 case GE: code = GT; break;
15295 case LEU: code = LT; break;
15296 case GEU: code = GT; break;
15297 default: gcc_unreachable ();
15300 compare_result2 = gen_reg_rtx (CCFPmode);
15306 cmp = (flag_finite_math_only && !flag_trapping_math)
15307 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15308 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15312 cmp = (flag_finite_math_only && !flag_trapping_math)
15313 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15314 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15318 cmp = (flag_finite_math_only && !flag_trapping_math)
15319 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15320 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15324 gcc_unreachable ();
15328 /* OR them together. */
15329 or_result = gen_reg_rtx (CCFPmode);
15330 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15332 compare_result = or_result;
15337 if (code == NE || code == LTGT)
15347 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15348 CLOBBERs to match cmptf_internal2 pattern. */
15349 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15350 && GET_MODE (op0) == TFmode
15351 && !TARGET_IEEEQUAD
15352 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15353 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15355 gen_rtx_SET (VOIDmode,
15357 gen_rtx_COMPARE (comp_mode, op0, op1)),
15358 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15359 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15360 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15361 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15362 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15363 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15364 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15365 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15366 else if (GET_CODE (op1) == UNSPEC
15367 && XINT (op1, 1) == UNSPEC_SP_TEST)
15369 rtx op1b = XVECEXP (op1, 0, 0);
15370 comp_mode = CCEQmode;
15371 compare_result = gen_reg_rtx (CCEQmode);
15373 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15375 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15378 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15379 gen_rtx_COMPARE (comp_mode, op0, op1)));
15382 /* Some kinds of FP comparisons need an OR operation;
15383 under flag_finite_math_only we don't bother. */
15384 if (FLOAT_MODE_P (mode)
15385 && !flag_finite_math_only
15386 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15387 && (code == LE || code == GE
15388 || code == UNEQ || code == LTGT
15389 || code == UNGT || code == UNLT))
15391 enum rtx_code or1, or2;
15392 rtx or1_rtx, or2_rtx, compare2_rtx;
15393 rtx or_result = gen_reg_rtx (CCEQmode);
15397 case LE: or1 = LT; or2 = EQ; break;
15398 case GE: or1 = GT; or2 = EQ; break;
15399 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15400 case LTGT: or1 = LT; or2 = GT; break;
15401 case UNGT: or1 = UNORDERED; or2 = GT; break;
15402 case UNLT: or1 = UNORDERED; or2 = LT; break;
15403 default: gcc_unreachable ();
15405 validate_condition_mode (or1, comp_mode);
15406 validate_condition_mode (or2, comp_mode);
15407 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15408 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15409 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15410 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15412 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15414 compare_result = or_result;
15418 validate_condition_mode (code, GET_MODE (compare_result));
15420 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15424 /* Emit the RTL for an sCOND pattern. */
15427 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15430 enum machine_mode op_mode;
15431 enum rtx_code cond_code;
15432 rtx result = operands[0];
15434 condition_rtx = rs6000_generate_compare (operands[1], mode);
15435 cond_code = GET_CODE (condition_rtx);
15437 op_mode = GET_MODE (XEXP (operands[1], 0));
15438 if (op_mode == VOIDmode)
15439 op_mode = GET_MODE (XEXP (operands[1], 1));
15441 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15443 PUT_MODE (condition_rtx, DImode);
15444 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15445 || cond_code == LTU)
15446 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15447 force_reg (DImode, const1_rtx),
15448 force_reg (DImode, const0_rtx),
15449 XEXP (condition_rtx, 0)));
15451 emit_insn (gen_isel_signed_di (result, condition_rtx,
15452 force_reg (DImode, const1_rtx),
15453 force_reg (DImode, const0_rtx),
15454 XEXP (condition_rtx, 0)));
15458 PUT_MODE (condition_rtx, SImode);
15459 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15460 || cond_code == LTU)
15461 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15462 force_reg (SImode, const1_rtx),
15463 force_reg (SImode, const0_rtx),
15464 XEXP (condition_rtx, 0)));
15466 emit_insn (gen_isel_signed_si (result, condition_rtx,
15467 force_reg (SImode, const1_rtx),
15468 force_reg (SImode, const0_rtx),
15469 XEXP (condition_rtx, 0)));
15474 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15477 enum machine_mode op_mode;
15478 enum rtx_code cond_code;
15479 rtx result = operands[0];
15481 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15483 rs6000_emit_sISEL (mode, operands);
15487 condition_rtx = rs6000_generate_compare (operands[1], mode);
15488 cond_code = GET_CODE (condition_rtx);
15490 if (FLOAT_MODE_P (mode)
15491 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15495 PUT_MODE (condition_rtx, SImode);
15496 t = XEXP (condition_rtx, 0);
15498 gcc_assert (cond_code == NE || cond_code == EQ);
15500 if (cond_code == NE)
15501 emit_insn (gen_e500_flip_gt_bit (t, t));
15503 emit_insn (gen_move_from_CR_gt_bit (result, t));
15507 if (cond_code == NE
15508 || cond_code == GE || cond_code == LE
15509 || cond_code == GEU || cond_code == LEU
15510 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15512 rtx not_result = gen_reg_rtx (CCEQmode);
15513 rtx not_op, rev_cond_rtx;
15514 enum machine_mode cc_mode;
15516 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15518 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15519 SImode, XEXP (condition_rtx, 0), const0_rtx);
15520 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15521 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15522 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15525 op_mode = GET_MODE (XEXP (operands[1], 0));
15526 if (op_mode == VOIDmode)
15527 op_mode = GET_MODE (XEXP (operands[1], 1));
15529 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15531 PUT_MODE (condition_rtx, DImode);
15532 convert_move (result, condition_rtx, 0);
15536 PUT_MODE (condition_rtx, SImode);
15537 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15541 /* Emit a branch of kind CODE to location LOC. */
15544 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15546 rtx condition_rtx, loc_ref;
15548 condition_rtx = rs6000_generate_compare (operands[0], mode);
15549 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15550 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15551 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15552 loc_ref, pc_rtx)));
15555 /* Return the string to output a conditional branch to LABEL, which is
15556 the operand number of the label, or -1 if the branch is really a
15557 conditional return.
15559 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15560 condition code register and its mode specifies what kind of
15561 comparison we made.
15563 REVERSED is nonzero if we should reverse the sense of the comparison.
15565 INSN is the insn. */
15568 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15570 static char string[64];
15571 enum rtx_code code = GET_CODE (op);
15572 rtx cc_reg = XEXP (op, 0);
15573 enum machine_mode mode = GET_MODE (cc_reg);
15574 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15575 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15576 int really_reversed = reversed ^ need_longbranch;
15582 validate_condition_mode (code, mode);
15584 /* Work out which way this really branches. We could use
15585 reverse_condition_maybe_unordered here always but this
15586 makes the resulting assembler clearer. */
15587 if (really_reversed)
15589 /* Reversal of FP compares takes care -- an ordered compare
15590 becomes an unordered compare and vice versa. */
15591 if (mode == CCFPmode)
15592 code = reverse_condition_maybe_unordered (code);
15594 code = reverse_condition (code);
15597 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15599 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15604 /* Opposite of GT. */
15613 gcc_unreachable ();
15619 /* Not all of these are actually distinct opcodes, but
15620 we distinguish them for clarity of the resulting assembler. */
15621 case NE: case LTGT:
15622 ccode = "ne"; break;
15623 case EQ: case UNEQ:
15624 ccode = "eq"; break;
15626 ccode = "ge"; break;
15627 case GT: case GTU: case UNGT:
15628 ccode = "gt"; break;
15630 ccode = "le"; break;
15631 case LT: case LTU: case UNLT:
15632 ccode = "lt"; break;
15633 case UNORDERED: ccode = "un"; break;
15634 case ORDERED: ccode = "nu"; break;
15635 case UNGE: ccode = "nl"; break;
15636 case UNLE: ccode = "ng"; break;
15638 gcc_unreachable ();
15641 /* Maybe we have a guess as to how likely the branch is.
15642 The old mnemonics don't have a way to specify this information. */
15644 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15645 if (note != NULL_RTX)
15647 /* PROB is the difference from 50%. */
15648 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15650 /* Only hint for highly probable/improbable branches on newer
15651 cpus as static prediction overrides processor dynamic
15652 prediction. For older cpus we may as well always hint, but
15653 assume not taken for branches that are very close to 50% as a
15654 mispredicted taken branch is more expensive than a
15655 mispredicted not-taken branch. */
15656 if (rs6000_always_hint
15657 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15658 && br_prob_note_reliable_p (note)))
15660 if (abs (prob) > REG_BR_PROB_BASE / 20
15661 && ((prob > 0) ^ need_longbranch))
15669 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15671 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15673 /* We need to escape any '%' characters in the reg_names string.
15674 Assume they'd only be the first character.... */
15675 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15677 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15681 /* If the branch distance was too far, we may have to use an
15682 unconditional branch to go the distance. */
15683 if (need_longbranch)
15684 s += sprintf (s, ",$+8\n\tb %s", label);
15686 s += sprintf (s, ",%s", label);
15692 /* Return the string to flip the GT bit on a CR. */
15694 output_e500_flip_gt_bit (rtx dst, rtx src)
15696 static char string[64];
15699 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15700 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15703 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15704 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15706 sprintf (string, "crnot %d,%d", a, b);
15710 /* Return insn for VSX or Altivec comparisons. */
15713 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15716 enum machine_mode mode = GET_MODE (op0);
15724 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15730 mask = gen_reg_rtx (mode);
15731 emit_insn (gen_rtx_SET (VOIDmode,
15733 gen_rtx_fmt_ee (code, mode, op0, op1)));
15740 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15741 DMODE is expected destination mode. This is a recursive function. */
15744 rs6000_emit_vector_compare (enum rtx_code rcode,
15746 enum machine_mode dmode)
15749 bool swap_operands = false;
15750 bool try_again = false;
15752 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15753 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15755 /* See if the comparison works as is. */
15756 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15764 swap_operands = true;
15769 swap_operands = true;
15777 /* Invert condition and try again.
15778 e.g., A != B becomes ~(A==B). */
15780 enum rtx_code rev_code;
15781 enum insn_code nor_code;
15784 rev_code = reverse_condition_maybe_unordered (rcode);
15785 if (rev_code == UNKNOWN)
15788 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15789 if (nor_code == CODE_FOR_nothing)
15792 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15796 mask = gen_reg_rtx (dmode);
15797 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15805 /* Try GT/GTU/LT/LTU OR EQ */
15808 enum insn_code ior_code;
15809 enum rtx_code new_code;
15830 gcc_unreachable ();
15833 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15834 if (ior_code == CODE_FOR_nothing)
15837 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15841 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15845 mask = gen_reg_rtx (dmode);
15846 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15864 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15869 /* You only get two chances. */
15873 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15874 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15875 operands for the relation operation COND. */
15878 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15879 rtx cond, rtx cc_op0, rtx cc_op1)
15881 enum machine_mode dest_mode = GET_MODE (dest);
15882 enum rtx_code rcode = GET_CODE (cond);
15883 enum machine_mode cc_mode = CCmode;
15887 bool invert_move = false;
15889 if (VECTOR_UNIT_NONE_P (dest_mode))
15894 /* Swap operands if we can, and fall back to doing the operation as
15895 specified, and doing a NOR to invert the test. */
15901 /* Invert condition and try again.
15902 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15903 invert_move = true;
15904 rcode = reverse_condition_maybe_unordered (rcode);
15905 if (rcode == UNKNOWN)
15909 /* Mark unsigned tests with CCUNSmode. */
15914 cc_mode = CCUNSmode;
15921 /* Get the vector mask for the given relational operations. */
15922 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15930 op_true = op_false;
15934 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15935 emit_insn (gen_rtx_SET (VOIDmode,
15937 gen_rtx_IF_THEN_ELSE (dest_mode,
15944 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15945 operands of the last comparison is nonzero/true, FALSE_COND if it
15946 is zero/false. Return 0 if the hardware has no such operation. */
15949 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15951 enum rtx_code code = GET_CODE (op);
15952 rtx op0 = XEXP (op, 0);
15953 rtx op1 = XEXP (op, 1);
15954 REAL_VALUE_TYPE c1;
15955 enum machine_mode compare_mode = GET_MODE (op0);
15956 enum machine_mode result_mode = GET_MODE (dest);
15958 bool is_against_zero;
15960 /* These modes should always match. */
15961 if (GET_MODE (op1) != compare_mode
15962 /* In the isel case however, we can use a compare immediate, so
15963 op1 may be a small constant. */
15964 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15966 if (GET_MODE (true_cond) != result_mode)
15968 if (GET_MODE (false_cond) != result_mode)
15971 /* First, work out if the hardware can do this at all, or
15972 if it's too slow.... */
15973 if (!FLOAT_MODE_P (compare_mode))
15976 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15979 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15980 && SCALAR_FLOAT_MODE_P (compare_mode))
15983 is_against_zero = op1 == CONST0_RTX (compare_mode);
15985 /* A floating-point subtract might overflow, underflow, or produce
15986 an inexact result, thus changing the floating-point flags, so it
15987 can't be generated if we care about that. It's safe if one side
15988 of the construct is zero, since then no subtract will be
15990 if (SCALAR_FLOAT_MODE_P (compare_mode)
15991 && flag_trapping_math && ! is_against_zero)
15994 /* Eliminate half of the comparisons by switching operands, this
15995 makes the remaining code simpler. */
15996 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15997 || code == LTGT || code == LT || code == UNLE)
15999 code = reverse_condition_maybe_unordered (code);
16001 true_cond = false_cond;
16005 /* UNEQ and LTGT take four instructions for a comparison with zero,
16006 it'll probably be faster to use a branch here too. */
16007 if (code == UNEQ && HONOR_NANS (compare_mode))
16010 if (GET_CODE (op1) == CONST_DOUBLE)
16011 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16013 /* We're going to try to implement comparisons by performing
16014 a subtract, then comparing against zero. Unfortunately,
16015 Inf - Inf is NaN which is not zero, and so if we don't
16016 know that the operand is finite and the comparison
16017 would treat EQ different to UNORDERED, we can't do it. */
16018 if (HONOR_INFINITIES (compare_mode)
16019 && code != GT && code != UNGE
16020 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16021 /* Constructs of the form (a OP b ? a : b) are safe. */
16022 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16023 || (! rtx_equal_p (op0, true_cond)
16024 && ! rtx_equal_p (op1, true_cond))))
16027 /* At this point we know we can use fsel. */
16029 /* Reduce the comparison to a comparison against zero. */
16030 if (! is_against_zero)
16032 temp = gen_reg_rtx (compare_mode);
16033 emit_insn (gen_rtx_SET (VOIDmode, temp,
16034 gen_rtx_MINUS (compare_mode, op0, op1)));
16036 op1 = CONST0_RTX (compare_mode);
16039 /* If we don't care about NaNs we can reduce some of the comparisons
16040 down to faster ones. */
16041 if (! HONOR_NANS (compare_mode))
16047 true_cond = false_cond;
16060 /* Now, reduce everything down to a GE. */
16067 temp = gen_reg_rtx (compare_mode);
16068 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16073 temp = gen_reg_rtx (compare_mode);
16074 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16079 temp = gen_reg_rtx (compare_mode);
16080 emit_insn (gen_rtx_SET (VOIDmode, temp,
16081 gen_rtx_NEG (compare_mode,
16082 gen_rtx_ABS (compare_mode, op0))));
16087 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16088 temp = gen_reg_rtx (result_mode);
16089 emit_insn (gen_rtx_SET (VOIDmode, temp,
16090 gen_rtx_IF_THEN_ELSE (result_mode,
16091 gen_rtx_GE (VOIDmode,
16093 true_cond, false_cond)));
16094 false_cond = true_cond;
16097 temp = gen_reg_rtx (compare_mode);
16098 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16103 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16104 temp = gen_reg_rtx (result_mode);
16105 emit_insn (gen_rtx_SET (VOIDmode, temp,
16106 gen_rtx_IF_THEN_ELSE (result_mode,
16107 gen_rtx_GE (VOIDmode,
16109 true_cond, false_cond)));
16110 true_cond = false_cond;
16113 temp = gen_reg_rtx (compare_mode);
16114 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16119 gcc_unreachable ();
16122 emit_insn (gen_rtx_SET (VOIDmode, dest,
16123 gen_rtx_IF_THEN_ELSE (result_mode,
16124 gen_rtx_GE (VOIDmode,
16126 true_cond, false_cond)));
16130 /* Same as above, but for ints (isel). */
16133 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16135 rtx condition_rtx, cr;
16136 enum machine_mode mode = GET_MODE (dest);
16138 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16141 /* We still have to do the compare, because isel doesn't do a
16142 compare, it just looks at the CRx bits set by a previous compare
16144 condition_rtx = rs6000_generate_compare (op, mode);
16145 cr = XEXP (condition_rtx, 0);
16147 if (mode == SImode)
16149 if (GET_MODE (cr) == CCmode)
16150 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16151 true_cond, false_cond, cr));
16153 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16154 true_cond, false_cond, cr));
16158 if (GET_MODE (cr) == CCmode)
16159 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16160 true_cond, false_cond, cr));
16162 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16163 true_cond, false_cond, cr));
16170 output_isel (rtx *operands)
16172 enum rtx_code code;
16174 code = GET_CODE (operands[1]);
16175 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16177 PUT_CODE (operands[1], reverse_condition (code));
16178 return "isel %0,%3,%2,%j1";
16181 return "isel %0,%2,%3,%j1";
16185 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16187 enum machine_mode mode = GET_MODE (op0);
16191 /* VSX/altivec have direct min/max insns. */
16192 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16194 emit_insn (gen_rtx_SET (VOIDmode,
16196 gen_rtx_fmt_ee (code, mode, op0, op1)));
16200 if (code == SMAX || code == SMIN)
16205 if (code == SMAX || code == UMAX)
16206 target = emit_conditional_move (dest, c, op0, op1, mode,
16207 op0, op1, mode, 0);
16209 target = emit_conditional_move (dest, c, op0, op1, mode,
16210 op1, op0, mode, 0);
16211 gcc_assert (target);
16212 if (target != dest)
16213 emit_move_insn (dest, target);
16216 /* Emit instructions to perform a load-reserved/store-conditional operation.
16217 The operation performed is an atomic
16218 (set M (CODE:MODE M OP))
16219 If not NULL, BEFORE is atomically set to M before the operation, and
16220 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16221 If SYNC_P then a memory barrier is emitted before the operation.
16222 Either OP or M may be wrapped in a NOT operation. */
16225 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16226 rtx m, rtx op, rtx before_param, rtx after_param,
16229 enum machine_mode used_mode;
16230 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16233 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16234 rtx shift = NULL_RTX;
16237 emit_insn (gen_lwsync ());
16241 /* If this is smaller than SImode, we'll have to use SImode with
16243 if (mode == QImode || mode == HImode)
16247 if (MEM_ALIGN (used_m) >= 32)
16250 if (BYTES_BIG_ENDIAN)
16251 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16253 shift = GEN_INT (ishift);
16254 used_m = change_address (used_m, SImode, 0);
16258 rtx addrSI, aligned_addr;
16259 int shift_mask = mode == QImode ? 0x18 : 0x10;
16261 addrSI = gen_lowpart_common (SImode,
16262 force_reg (Pmode, XEXP (used_m, 0)));
16263 addrSI = force_reg (SImode, addrSI);
16264 shift = gen_reg_rtx (SImode);
16266 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16267 GEN_INT (shift_mask)));
16268 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16270 aligned_addr = expand_binop (Pmode, and_optab,
16272 GEN_INT (-4), NULL_RTX,
16273 1, OPTAB_LIB_WIDEN);
16274 used_m = change_address (used_m, SImode, aligned_addr);
16275 set_mem_align (used_m, 32);
16277 /* It's safe to keep the old alias set of USED_M, because
16278 the operation is atomic and only affects the original
16282 if (GET_CODE (op) == NOT)
16284 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16285 oldop = gen_rtx_NOT (SImode, oldop);
16288 oldop = lowpart_subreg (SImode, op, mode);
16294 newop = expand_binop (SImode, and_optab,
16295 oldop, GEN_INT (imask), NULL_RTX,
16296 1, OPTAB_LIB_WIDEN);
16297 emit_insn (gen_ashlsi3 (newop, newop, shift));
16300 case NOT: /* NAND */
16301 newop = expand_binop (SImode, ior_optab,
16302 oldop, GEN_INT (~imask), NULL_RTX,
16303 1, OPTAB_LIB_WIDEN);
16304 emit_insn (gen_rotlsi3 (newop, newop, shift));
16308 newop = expand_binop (SImode, ior_optab,
16309 oldop, GEN_INT (~imask), NULL_RTX,
16310 1, OPTAB_LIB_WIDEN);
16311 emit_insn (gen_rotlsi3 (newop, newop, shift));
16319 newop = expand_binop (SImode, and_optab,
16320 oldop, GEN_INT (imask), NULL_RTX,
16321 1, OPTAB_LIB_WIDEN);
16322 emit_insn (gen_ashlsi3 (newop, newop, shift));
16324 mask = gen_reg_rtx (SImode);
16325 emit_move_insn (mask, GEN_INT (imask));
16326 emit_insn (gen_ashlsi3 (mask, mask, shift));
16329 newop = gen_rtx_PLUS (SImode, m, newop);
16331 newop = gen_rtx_MINUS (SImode, m, newop);
16332 newop = gen_rtx_AND (SImode, newop, mask);
16333 newop = gen_rtx_IOR (SImode, newop,
16334 gen_rtx_AND (SImode,
16335 gen_rtx_NOT (SImode, mask),
16341 gcc_unreachable ();
16345 used_mode = SImode;
16346 before = gen_reg_rtx (used_mode);
16347 after = gen_reg_rtx (used_mode);
16352 before = before_param;
16353 after = after_param;
16355 if (before == NULL_RTX)
16356 before = gen_reg_rtx (used_mode);
16357 if (after == NULL_RTX)
16358 after = gen_reg_rtx (used_mode);
16361 if ((code == PLUS || code == MINUS)
16362 && used_mode != mode)
16363 the_op = op; /* Computed above. */
16364 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16365 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16366 else if (code == NOT)
16367 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16368 gen_rtx_NOT (used_mode, m),
16369 gen_rtx_NOT (used_mode, op));
16371 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16373 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16374 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16375 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16376 gen_rtx_UNSPEC (used_mode,
16377 gen_rtvec (1, the_op),
16379 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16381 if ((code == PLUS || code == MINUS) && used_mode != mode)
16382 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16383 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16385 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16386 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16388 /* Shift and mask the return values properly. */
16389 if (used_mode != mode && before_param)
16391 emit_insn (gen_lshrsi3 (before, before, shift));
16392 convert_move (before_param, before, 1);
16395 if (used_mode != mode && after_param)
16397 emit_insn (gen_lshrsi3 (after, after, shift));
16398 convert_move (after_param, after, 1);
16401 /* The previous sequence will end with a branch that's dependent on
16402 the conditional store, so placing an isync will ensure that no
16403 other instructions (especially, no load or store instructions)
16404 can start before the atomic operation completes. */
16406 emit_insn (gen_isync ());
16409 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16410 COND is true. Mark the jump as unlikely to be taken. */
16413 emit_unlikely_jump (rtx cond, rtx label)
16415 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16418 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16419 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16420 add_reg_note (x, REG_BR_PROB, very_unlikely);
16423 /* A subroutine of the atomic operation splitters. Emit a load-locked
16424 instruction in MODE. */
16427 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16429 rtx (*fn) (rtx, rtx) = NULL;
16430 if (mode == SImode)
16431 fn = gen_load_locked_si;
16432 else if (mode == DImode)
16433 fn = gen_load_locked_di;
16434 emit_insn (fn (reg, mem));
16437 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16438 instruction in MODE. */
16441 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16443 rtx (*fn) (rtx, rtx, rtx) = NULL;
16444 if (mode == SImode)
16445 fn = gen_store_conditional_si;
16446 else if (mode == DImode)
16447 fn = gen_store_conditional_di;
16449 /* Emit sync before stwcx. to address PPC405 Erratum. */
16450 if (PPC405_ERRATUM77)
16451 emit_insn (gen_memory_barrier ());
16453 emit_insn (fn (res, mem, val));
16456 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16457 to perform. MEM is the memory on which to operate. VAL is the second
16458 operand of the binary operator. BEFORE and AFTER are optional locations to
16459 return the value of MEM either before of after the operation. SCRATCH is
16460 a scratch register. */
16463 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16464 rtx before, rtx after, rtx scratch)
16466 enum machine_mode mode = GET_MODE (mem);
16467 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16469 emit_insn (gen_lwsync ());
16471 label = gen_label_rtx ();
16472 emit_label (label);
16473 label = gen_rtx_LABEL_REF (VOIDmode, label);
16475 if (before == NULL_RTX)
16477 emit_load_locked (mode, before, mem);
16480 x = gen_rtx_IOR (mode,
16481 gen_rtx_NOT (mode, before),
16482 gen_rtx_NOT (mode, val));
16483 else if (code == AND)
16484 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16486 x = gen_rtx_fmt_ee (code, mode, before, val);
16488 if (after != NULL_RTX)
16489 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16490 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16492 emit_store_conditional (mode, cond, mem, scratch);
16494 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16495 emit_unlikely_jump (x, label);
16497 emit_insn (gen_isync ());
16500 /* Expand an atomic compare and swap operation. MEM is the memory on which
16501 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16502 value to be stored. SCRATCH is a scratch GPR. */
16505 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16508 enum machine_mode mode = GET_MODE (mem);
16509 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16511 emit_insn (gen_lwsync ());
16513 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16514 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16515 emit_label (XEXP (label1, 0));
16517 emit_load_locked (mode, retval, mem);
16519 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16520 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16522 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16523 emit_unlikely_jump (x, label2);
16525 emit_move_insn (scratch, newval);
16526 emit_store_conditional (mode, cond, mem, scratch);
16528 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16529 emit_unlikely_jump (x, label1);
16531 emit_insn (gen_isync ());
16532 emit_label (XEXP (label2, 0));
16535 /* Expand an atomic test and set operation. MEM is the memory on which
16536 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16539 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16541 enum machine_mode mode = GET_MODE (mem);
16542 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16544 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16545 emit_label (XEXP (label, 0));
16547 emit_load_locked (mode, retval, mem);
16548 emit_move_insn (scratch, val);
16549 emit_store_conditional (mode, cond, mem, scratch);
16551 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16552 emit_unlikely_jump (x, label);
16554 emit_insn (gen_isync ());
16558 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16560 enum machine_mode mode = GET_MODE (mem);
16561 rtx addrSI, align, wdst, shift, mask;
16562 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16563 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16565 /* Shift amount for subword relative to aligned word. */
16566 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16567 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16568 shift = gen_reg_rtx (SImode);
16569 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16570 GEN_INT (shift_mask)));
16571 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16573 /* Shift and mask old value into position within word. */
16574 oldval = convert_modes (SImode, mode, oldval, 1);
16575 oldval = expand_binop (SImode, and_optab,
16576 oldval, GEN_INT (imask), NULL_RTX,
16577 1, OPTAB_LIB_WIDEN);
16578 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16580 /* Shift and mask new value into position within word. */
16581 newval = convert_modes (SImode, mode, newval, 1);
16582 newval = expand_binop (SImode, and_optab,
16583 newval, GEN_INT (imask), NULL_RTX,
16584 1, OPTAB_LIB_WIDEN);
16585 emit_insn (gen_ashlsi3 (newval, newval, shift));
16587 /* Mask for insertion. */
16588 mask = gen_reg_rtx (SImode);
16589 emit_move_insn (mask, GEN_INT (imask));
16590 emit_insn (gen_ashlsi3 (mask, mask, shift));
16592 /* Address of aligned word containing subword. */
16593 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16594 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16595 mem = change_address (mem, SImode, align);
16596 set_mem_align (mem, 32);
16597 MEM_VOLATILE_P (mem) = 1;
16599 wdst = gen_reg_rtx (SImode);
16600 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16601 oldval, newval, mem));
16603 /* Shift the result back. */
16604 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16606 emit_move_insn (dst, gen_lowpart (mode, wdst));
16610 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16611 rtx oldval, rtx newval, rtx mem,
16614 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16616 emit_insn (gen_lwsync ());
16617 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16618 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16619 emit_label (XEXP (label1, 0));
16621 emit_load_locked (SImode, scratch, mem);
16623 /* Mask subword within loaded value for comparison with oldval.
16624 Use UNSPEC_AND to avoid clobber.*/
16625 emit_insn (gen_rtx_SET (SImode, dest,
16626 gen_rtx_UNSPEC (SImode,
16627 gen_rtvec (2, scratch, mask),
16630 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16631 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16633 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16634 emit_unlikely_jump (x, label2);
16636 /* Clear subword within loaded value for insertion of new value. */
16637 emit_insn (gen_rtx_SET (SImode, scratch,
16638 gen_rtx_AND (SImode,
16639 gen_rtx_NOT (SImode, mask), scratch)));
16640 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16641 emit_store_conditional (SImode, cond, mem, scratch);
16643 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16644 emit_unlikely_jump (x, label1);
16646 emit_insn (gen_isync ());
16647 emit_label (XEXP (label2, 0));
16651 /* Emit instructions to move SRC to DST. Called by splitters for
16652 multi-register moves. It will emit at most one instruction for
16653 each register that is accessed; that is, it won't emit li/lis pairs
16654 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16658 rs6000_split_multireg_move (rtx dst, rtx src)
16660 /* The register number of the first register being moved. */
16662 /* The mode that is to be moved. */
16663 enum machine_mode mode;
16664 /* The mode that the move is being done in, and its size. */
16665 enum machine_mode reg_mode;
16667 /* The number of registers that will be moved. */
16670 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16671 mode = GET_MODE (dst);
16672 nregs = hard_regno_nregs[reg][mode];
16673 if (FP_REGNO_P (reg))
16674 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16675 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16676 else if (ALTIVEC_REGNO_P (reg))
16677 reg_mode = V16QImode;
16678 else if (TARGET_E500_DOUBLE && mode == TFmode)
16681 reg_mode = word_mode;
16682 reg_mode_size = GET_MODE_SIZE (reg_mode);
16684 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16686 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16688 /* Move register range backwards, if we might have destructive
16691 for (i = nregs - 1; i >= 0; i--)
16692 emit_insn (gen_rtx_SET (VOIDmode,
16693 simplify_gen_subreg (reg_mode, dst, mode,
16694 i * reg_mode_size),
16695 simplify_gen_subreg (reg_mode, src, mode,
16696 i * reg_mode_size)));
16702 bool used_update = false;
16704 if (MEM_P (src) && INT_REGNO_P (reg))
16708 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16709 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16712 breg = XEXP (XEXP (src, 0), 0);
16713 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16714 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16715 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16716 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16717 src = replace_equiv_address (src, breg);
16719 else if (! rs6000_offsettable_memref_p (src))
16722 basereg = gen_rtx_REG (Pmode, reg);
16723 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16724 src = replace_equiv_address (src, basereg);
16727 breg = XEXP (src, 0);
16728 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16729 breg = XEXP (breg, 0);
16731 /* If the base register we are using to address memory is
16732 also a destination reg, then change that register last. */
16734 && REGNO (breg) >= REGNO (dst)
16735 && REGNO (breg) < REGNO (dst) + nregs)
16736 j = REGNO (breg) - REGNO (dst);
16739 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16743 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16744 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16747 breg = XEXP (XEXP (dst, 0), 0);
16748 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16749 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16750 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16752 /* We have to update the breg before doing the store.
16753 Use store with update, if available. */
16757 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16758 emit_insn (TARGET_32BIT
16759 ? (TARGET_POWERPC64
16760 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16761 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16762 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16763 used_update = true;
16766 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16767 dst = replace_equiv_address (dst, breg);
16770 gcc_assert (rs6000_offsettable_memref_p (dst));
16773 for (i = 0; i < nregs; i++)
16775 /* Calculate index to next subword. */
16780 /* If compiler already emitted move of first word by
16781 store with update, no need to do anything. */
16782 if (j == 0 && used_update)
16785 emit_insn (gen_rtx_SET (VOIDmode,
16786 simplify_gen_subreg (reg_mode, dst, mode,
16787 j * reg_mode_size),
16788 simplify_gen_subreg (reg_mode, src, mode,
16789 j * reg_mode_size)));
16795 /* This page contains routines that are used to determine what the
16796 function prologue and epilogue code will do and write them out. */
16798 /* Return the first fixed-point register that is required to be
16799 saved. 32 if none. */
16802 first_reg_to_save (void)
16806 /* Find lowest numbered live register. */
16807 for (first_reg = 13; first_reg <= 31; first_reg++)
16808 if (df_regs_ever_live_p (first_reg)
16809 && (! call_used_regs[first_reg]
16810 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16811 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16812 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16813 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16818 && crtl->uses_pic_offset_table
16819 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16820 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16826 /* Similar, for FP regs. */
16829 first_fp_reg_to_save (void)
16833 /* Find lowest numbered live register. */
16834 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16835 if (df_regs_ever_live_p (first_reg))
16841 /* Similar, for AltiVec regs. */
16844 first_altivec_reg_to_save (void)
16848 /* Stack frame remains as is unless we are in AltiVec ABI. */
16849 if (! TARGET_ALTIVEC_ABI)
16850 return LAST_ALTIVEC_REGNO + 1;
16852 /* On Darwin, the unwind routines are compiled without
16853 TARGET_ALTIVEC, and use save_world to save/restore the
16854 altivec registers when necessary. */
16855 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16856 && ! TARGET_ALTIVEC)
16857 return FIRST_ALTIVEC_REGNO + 20;
16859 /* Find lowest numbered live register. */
16860 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16861 if (df_regs_ever_live_p (i))
16867 /* Return a 32-bit mask of the AltiVec registers we need to set in
16868 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16869 the 32-bit word is 0. */
16871 static unsigned int
16872 compute_vrsave_mask (void)
16874 unsigned int i, mask = 0;
16876 /* On Darwin, the unwind routines are compiled without
16877 TARGET_ALTIVEC, and use save_world to save/restore the
16878 call-saved altivec registers when necessary. */
16879 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16880 && ! TARGET_ALTIVEC)
16883 /* First, find out if we use _any_ altivec registers. */
16884 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16885 if (df_regs_ever_live_p (i))
16886 mask |= ALTIVEC_REG_BIT (i);
16891 /* Next, remove the argument registers from the set. These must
16892 be in the VRSAVE mask set by the caller, so we don't need to add
16893 them in again. More importantly, the mask we compute here is
16894 used to generate CLOBBERs in the set_vrsave insn, and we do not
16895 wish the argument registers to die. */
16896 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16897 mask &= ~ALTIVEC_REG_BIT (i);
16899 /* Similarly, remove the return value from the set. */
16902 diddle_return_value (is_altivec_return_reg, &yes);
16904 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16910 /* For a very restricted set of circumstances, we can cut down the
16911 size of prologues/epilogues by calling our own save/restore-the-world
16915 compute_save_world_info (rs6000_stack_t *info_ptr)
16917 info_ptr->world_save_p = 1;
16918 info_ptr->world_save_p
16919 = (WORLD_SAVE_P (info_ptr)
16920 && DEFAULT_ABI == ABI_DARWIN
16921 && ! (cfun->calls_setjmp && flag_exceptions)
16922 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16923 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16924 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16925 && info_ptr->cr_save_p);
16927 /* This will not work in conjunction with sibcalls. Make sure there
16928 are none. (This check is expensive, but seldom executed.) */
16929 if (WORLD_SAVE_P (info_ptr))
16932 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16933 if ( GET_CODE (insn) == CALL_INSN
16934 && SIBLING_CALL_P (insn))
16936 info_ptr->world_save_p = 0;
16941 if (WORLD_SAVE_P (info_ptr))
16943 /* Even if we're not touching VRsave, make sure there's room on the
16944 stack for it, if it looks like we're calling SAVE_WORLD, which
16945 will attempt to save it. */
16946 info_ptr->vrsave_size = 4;
16948 /* If we are going to save the world, we need to save the link register too. */
16949 info_ptr->lr_save_p = 1;
16951 /* "Save" the VRsave register too if we're saving the world. */
16952 if (info_ptr->vrsave_mask == 0)
16953 info_ptr->vrsave_mask = compute_vrsave_mask ();
16955 /* Because the Darwin register save/restore routines only handle
16956 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16958 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16959 && (info_ptr->first_altivec_reg_save
16960 >= FIRST_SAVED_ALTIVEC_REGNO));
16967 is_altivec_return_reg (rtx reg, void *xyes)
16969 bool *yes = (bool *) xyes;
16970 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16975 /* Calculate the stack information for the current function. This is
16976 complicated by having two separate calling sequences, the AIX calling
16977 sequence and the V.4 calling sequence.
16979 AIX (and Darwin/Mac OS X) stack frames look like:
16981 SP----> +---------------------------------------+
16982 | back chain to caller | 0 0
16983 +---------------------------------------+
16984 | saved CR | 4 8 (8-11)
16985 +---------------------------------------+
16987 +---------------------------------------+
16988 | reserved for compilers | 12 24
16989 +---------------------------------------+
16990 | reserved for binders | 16 32
16991 +---------------------------------------+
16992 | saved TOC pointer | 20 40
16993 +---------------------------------------+
16994 | Parameter save area (P) | 24 48
16995 +---------------------------------------+
16996 | Alloca space (A) | 24+P etc.
16997 +---------------------------------------+
16998 | Local variable space (L) | 24+P+A
16999 +---------------------------------------+
17000 | Float/int conversion temporary (X) | 24+P+A+L
17001 +---------------------------------------+
17002 | Save area for AltiVec registers (W) | 24+P+A+L+X
17003 +---------------------------------------+
17004 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17005 +---------------------------------------+
17006 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17007 +---------------------------------------+
17008 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17009 +---------------------------------------+
17010 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17011 +---------------------------------------+
17012 old SP->| back chain to caller's caller |
17013 +---------------------------------------+
17015 The required alignment for AIX configurations is two words (i.e., 8
17019 V.4 stack frames look like:
17021 SP----> +---------------------------------------+
17022 | back chain to caller | 0
17023 +---------------------------------------+
17024 | caller's saved LR | 4
17025 +---------------------------------------+
17026 | Parameter save area (P) | 8
17027 +---------------------------------------+
17028 | Alloca space (A) | 8+P
17029 +---------------------------------------+
17030 | Varargs save area (V) | 8+P+A
17031 +---------------------------------------+
17032 | Local variable space (L) | 8+P+A+V
17033 +---------------------------------------+
17034 | Float/int conversion temporary (X) | 8+P+A+V+L
17035 +---------------------------------------+
17036 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17037 +---------------------------------------+
17038 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17039 +---------------------------------------+
17040 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17041 +---------------------------------------+
17042 | SPE: area for 64-bit GP registers |
17043 +---------------------------------------+
17044 | SPE alignment padding |
17045 +---------------------------------------+
17046 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17047 +---------------------------------------+
17048 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17049 +---------------------------------------+
17050 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17051 +---------------------------------------+
17052 old SP->| back chain to caller's caller |
17053 +---------------------------------------+
17055 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17056 given. (But note below and in sysv4.h that we require only 8 and
17057 may round up the size of our stack frame anyways. The historical
17058 reason is early versions of powerpc-linux which didn't properly
17059 align the stack at program startup. A happy side-effect is that
17060 -mno-eabi libraries can be used with -meabi programs.)
17062 The EABI configuration defaults to the V.4 layout. However,
17063 the stack alignment requirements may differ. If -mno-eabi is not
17064 given, the required stack alignment is 8 bytes; if -mno-eabi is
17065 given, the required alignment is 16 bytes. (But see V.4 comment
17068 #ifndef ABI_STACK_BOUNDARY
17069 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17072 static rs6000_stack_t *
17073 rs6000_stack_info (void)
17075 static rs6000_stack_t info;
17076 rs6000_stack_t *info_ptr = &info;
17077 int reg_size = TARGET_32BIT ? 4 : 8;
17081 HOST_WIDE_INT non_fixed_size;
17083 memset (&info, 0, sizeof (info));
17087 /* Cache value so we don't rescan instruction chain over and over. */
17088 if (cfun->machine->insn_chain_scanned_p == 0)
17089 cfun->machine->insn_chain_scanned_p
17090 = spe_func_has_64bit_regs_p () + 1;
17091 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17094 /* Select which calling sequence. */
17095 info_ptr->abi = DEFAULT_ABI;
17097 /* Calculate which registers need to be saved & save area size. */
17098 info_ptr->first_gp_reg_save = first_reg_to_save ();
17099 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17100 even if it currently looks like we won't. Reload may need it to
17101 get at a constant; if so, it will have already created a constant
17102 pool entry for it. */
17103 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17104 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17105 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17106 && crtl->uses_const_pool
17107 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17108 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17110 first_gp = info_ptr->first_gp_reg_save;
17112 info_ptr->gp_size = reg_size * (32 - first_gp);
17114 /* For the SPE, we have an additional upper 32-bits on each GPR.
17115 Ideally we should save the entire 64-bits only when the upper
17116 half is used in SIMD instructions. Since we only record
17117 registers live (not the size they are used in), this proves
17118 difficult because we'd have to traverse the instruction chain at
17119 the right time, taking reload into account. This is a real pain,
17120 so we opt to save the GPRs in 64-bits always if but one register
17121 gets used in 64-bits. Otherwise, all the registers in the frame
17122 get saved in 32-bits.
17124 So... since when we save all GPRs (except the SP) in 64-bits, the
17125 traditional GP save area will be empty. */
17126 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17127 info_ptr->gp_size = 0;
17129 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17130 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17132 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17133 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17134 - info_ptr->first_altivec_reg_save);
17136 /* Does this function call anything? */
17137 info_ptr->calls_p = (! current_function_is_leaf
17138 || cfun->machine->ra_needs_full_frame);
17140 /* Determine if we need to save the link register. */
17141 if ((DEFAULT_ABI == ABI_AIX
17143 && !TARGET_PROFILE_KERNEL)
17144 #ifdef TARGET_RELOCATABLE
17145 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17147 || (info_ptr->first_fp_reg_save != 64
17148 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17149 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17150 || info_ptr->calls_p
17151 || rs6000_ra_ever_killed ())
17153 info_ptr->lr_save_p = 1;
17154 df_set_regs_ever_live (LR_REGNO, true);
17157 /* Determine if we need to save the condition code registers. */
17158 if (df_regs_ever_live_p (CR2_REGNO)
17159 || df_regs_ever_live_p (CR3_REGNO)
17160 || df_regs_ever_live_p (CR4_REGNO))
17162 info_ptr->cr_save_p = 1;
17163 if (DEFAULT_ABI == ABI_V4)
17164 info_ptr->cr_size = reg_size;
17167 /* If the current function calls __builtin_eh_return, then we need
17168 to allocate stack space for registers that will hold data for
17169 the exception handler. */
17170 if (crtl->calls_eh_return)
17173 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17176 /* SPE saves EH registers in 64-bits. */
17177 ehrd_size = i * (TARGET_SPE_ABI
17178 && info_ptr->spe_64bit_regs_used != 0
17179 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17184 /* Determine various sizes. */
17185 info_ptr->reg_size = reg_size;
17186 info_ptr->fixed_size = RS6000_SAVE_AREA;
17187 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17188 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17189 TARGET_ALTIVEC ? 16 : 8);
17190 if (FRAME_GROWS_DOWNWARD)
17191 info_ptr->vars_size
17192 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17193 + info_ptr->parm_size,
17194 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17195 - (info_ptr->fixed_size + info_ptr->vars_size
17196 + info_ptr->parm_size);
17198 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17199 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17201 info_ptr->spe_gp_size = 0;
17203 if (TARGET_ALTIVEC_ABI)
17204 info_ptr->vrsave_mask = compute_vrsave_mask ();
17206 info_ptr->vrsave_mask = 0;
17208 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17209 info_ptr->vrsave_size = 4;
17211 info_ptr->vrsave_size = 0;
17213 compute_save_world_info (info_ptr);
17215 /* Calculate the offsets. */
17216 switch (DEFAULT_ABI)
17220 gcc_unreachable ();
17224 info_ptr->fp_save_offset = - info_ptr->fp_size;
17225 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17227 if (TARGET_ALTIVEC_ABI)
17229 info_ptr->vrsave_save_offset
17230 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17232 /* Align stack so vector save area is on a quadword boundary.
17233 The padding goes above the vectors. */
17234 if (info_ptr->altivec_size != 0)
17235 info_ptr->altivec_padding_size
17236 = info_ptr->vrsave_save_offset & 0xF;
17238 info_ptr->altivec_padding_size = 0;
17240 info_ptr->altivec_save_offset
17241 = info_ptr->vrsave_save_offset
17242 - info_ptr->altivec_padding_size
17243 - info_ptr->altivec_size;
17244 gcc_assert (info_ptr->altivec_size == 0
17245 || info_ptr->altivec_save_offset % 16 == 0);
17247 /* Adjust for AltiVec case. */
17248 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17251 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17252 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17253 info_ptr->lr_save_offset = 2*reg_size;
17257 info_ptr->fp_save_offset = - info_ptr->fp_size;
17258 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17259 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17261 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17263 /* Align stack so SPE GPR save area is aligned on a
17264 double-word boundary. */
17265 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17266 info_ptr->spe_padding_size
17267 = 8 - (-info_ptr->cr_save_offset % 8);
17269 info_ptr->spe_padding_size = 0;
17271 info_ptr->spe_gp_save_offset
17272 = info_ptr->cr_save_offset
17273 - info_ptr->spe_padding_size
17274 - info_ptr->spe_gp_size;
17276 /* Adjust for SPE case. */
17277 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17279 else if (TARGET_ALTIVEC_ABI)
17281 info_ptr->vrsave_save_offset
17282 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17284 /* Align stack so vector save area is on a quadword boundary. */
17285 if (info_ptr->altivec_size != 0)
17286 info_ptr->altivec_padding_size
17287 = 16 - (-info_ptr->vrsave_save_offset % 16);
17289 info_ptr->altivec_padding_size = 0;
17291 info_ptr->altivec_save_offset
17292 = info_ptr->vrsave_save_offset
17293 - info_ptr->altivec_padding_size
17294 - info_ptr->altivec_size;
17296 /* Adjust for AltiVec case. */
17297 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17300 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17301 info_ptr->ehrd_offset -= ehrd_size;
17302 info_ptr->lr_save_offset = reg_size;
17306 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17307 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17308 + info_ptr->gp_size
17309 + info_ptr->altivec_size
17310 + info_ptr->altivec_padding_size
17311 + info_ptr->spe_gp_size
17312 + info_ptr->spe_padding_size
17314 + info_ptr->cr_size
17315 + info_ptr->vrsave_size,
17318 non_fixed_size = (info_ptr->vars_size
17319 + info_ptr->parm_size
17320 + info_ptr->save_size);
17322 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17323 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17325 /* Determine if we need to allocate any stack frame:
17327 For AIX we need to push the stack if a frame pointer is needed
17328 (because the stack might be dynamically adjusted), if we are
17329 debugging, if we make calls, or if the sum of fp_save, gp_save,
17330 and local variables are more than the space needed to save all
17331 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17332 + 18*8 = 288 (GPR13 reserved).
17334 For V.4 we don't have the stack cushion that AIX uses, but assume
17335 that the debugger can handle stackless frames. */
17337 if (info_ptr->calls_p)
17338 info_ptr->push_p = 1;
17340 else if (DEFAULT_ABI == ABI_V4)
17341 info_ptr->push_p = non_fixed_size != 0;
17343 else if (frame_pointer_needed)
17344 info_ptr->push_p = 1;
17346 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17347 info_ptr->push_p = 1;
17350 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17352 /* Zero offsets if we're not saving those registers. */
17353 if (info_ptr->fp_size == 0)
17354 info_ptr->fp_save_offset = 0;
17356 if (info_ptr->gp_size == 0)
17357 info_ptr->gp_save_offset = 0;
17359 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17360 info_ptr->altivec_save_offset = 0;
17362 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17363 info_ptr->vrsave_save_offset = 0;
17365 if (! TARGET_SPE_ABI
17366 || info_ptr->spe_64bit_regs_used == 0
17367 || info_ptr->spe_gp_size == 0)
17368 info_ptr->spe_gp_save_offset = 0;
17370 if (! info_ptr->lr_save_p)
17371 info_ptr->lr_save_offset = 0;
17373 if (! info_ptr->cr_save_p)
17374 info_ptr->cr_save_offset = 0;
17379 /* Return true if the current function uses any GPRs in 64-bit SIMD
17383 spe_func_has_64bit_regs_p (void)
17387 /* Functions that save and restore all the call-saved registers will
17388 need to save/restore the registers in 64-bits. */
17389 if (crtl->calls_eh_return
17390 || cfun->calls_setjmp
17391 || crtl->has_nonlocal_goto)
17394 insns = get_insns ();
17396 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17402 /* FIXME: This should be implemented with attributes...
17404 (set_attr "spe64" "true")....then,
17405 if (get_spe64(insn)) return true;
17407 It's the only reliable way to do the stuff below. */
17409 i = PATTERN (insn);
17410 if (GET_CODE (i) == SET)
17412 enum machine_mode mode = GET_MODE (SET_SRC (i));
17414 if (SPE_VECTOR_MODE (mode))
17416 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17426 debug_stack_info (rs6000_stack_t *info)
17428 const char *abi_string;
17431 info = rs6000_stack_info ();
17433 fprintf (stderr, "\nStack information for function %s:\n",
17434 ((current_function_decl && DECL_NAME (current_function_decl))
17435 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17440 default: abi_string = "Unknown"; break;
17441 case ABI_NONE: abi_string = "NONE"; break;
17442 case ABI_AIX: abi_string = "AIX"; break;
17443 case ABI_DARWIN: abi_string = "Darwin"; break;
17444 case ABI_V4: abi_string = "V.4"; break;
17447 fprintf (stderr, "\tABI = %5s\n", abi_string);
17449 if (TARGET_ALTIVEC_ABI)
17450 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17452 if (TARGET_SPE_ABI)
17453 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17455 if (info->first_gp_reg_save != 32)
17456 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17458 if (info->first_fp_reg_save != 64)
17459 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17461 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17462 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17463 info->first_altivec_reg_save);
17465 if (info->lr_save_p)
17466 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17468 if (info->cr_save_p)
17469 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17471 if (info->vrsave_mask)
17472 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17475 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17478 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17480 if (info->gp_save_offset)
17481 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17483 if (info->fp_save_offset)
17484 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17486 if (info->altivec_save_offset)
17487 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17488 info->altivec_save_offset);
17490 if (info->spe_gp_save_offset)
17491 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17492 info->spe_gp_save_offset);
17494 if (info->vrsave_save_offset)
17495 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17496 info->vrsave_save_offset);
17498 if (info->lr_save_offset)
17499 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17501 if (info->cr_save_offset)
17502 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17504 if (info->varargs_save_offset)
17505 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17507 if (info->total_size)
17508 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17511 if (info->vars_size)
17512 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17515 if (info->parm_size)
17516 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17518 if (info->fixed_size)
17519 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17522 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17524 if (info->spe_gp_size)
17525 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17528 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17530 if (info->altivec_size)
17531 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17533 if (info->vrsave_size)
17534 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17536 if (info->altivec_padding_size)
17537 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17538 info->altivec_padding_size);
17540 if (info->spe_padding_size)
17541 fprintf (stderr, "\tspe_padding_size = %5d\n",
17542 info->spe_padding_size);
17545 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17547 if (info->save_size)
17548 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17550 if (info->reg_size != 4)
17551 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17553 fprintf (stderr, "\n");
17557 rs6000_return_addr (int count, rtx frame)
17559 /* Currently we don't optimize very well between prolog and body
17560 code and for PIC code the code can be actually quite bad, so
17561 don't try to be too clever here. */
17562 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17564 cfun->machine->ra_needs_full_frame = 1;
17571 plus_constant (copy_to_reg
17572 (gen_rtx_MEM (Pmode,
17573 memory_address (Pmode, frame))),
17574 RETURN_ADDRESS_OFFSET)));
17577 cfun->machine->ra_need_lr = 1;
17578 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17581 /* Say whether a function is a candidate for sibcall handling or not.
17582 We do not allow indirect calls to be optimized into sibling calls.
17583 Also, we can't do it if there are any vector parameters; there's
17584 nowhere to put the VRsave code so it works; note that functions with
17585 vector parameters are required to have a prototype, so the argument
17586 type info must be available here. (The tail recursion case can work
17587 with vector parameters, but there's no way to distinguish here.) */
17589 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17594 if (TARGET_ALTIVEC_VRSAVE)
17596 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17597 type; type = TREE_CHAIN (type))
17599 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17603 if (DEFAULT_ABI == ABI_DARWIN
17604 || ((*targetm.binds_local_p) (decl)
17605 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17607 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17609 if (!lookup_attribute ("longcall", attr_list)
17610 || lookup_attribute ("shortcall", attr_list))
17617 /* NULL if INSN insn is valid within a low-overhead loop.
17618 Otherwise return why doloop cannot be applied.
17619 PowerPC uses the COUNT register for branch on table instructions. */
17621 static const char *
17622 rs6000_invalid_within_doloop (const_rtx insn)
17625 return "Function call in the loop.";
17628 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17629 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17630 return "Computed branch in the loop.";
17636 rs6000_ra_ever_killed (void)
17642 if (cfun->is_thunk)
17645 /* regs_ever_live has LR marked as used if any sibcalls are present,
17646 but this should not force saving and restoring in the
17647 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17648 clobbers LR, so that is inappropriate. */
17650 /* Also, the prologue can generate a store into LR that
17651 doesn't really count, like this:
17654 bcl to set PIC register
17658 When we're called from the epilogue, we need to avoid counting
17659 this as a store. */
17661 push_topmost_sequence ();
17662 top = get_insns ();
17663 pop_topmost_sequence ();
17664 reg = gen_rtx_REG (Pmode, LR_REGNO);
17666 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17672 if (!SIBLING_CALL_P (insn))
17675 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17677 else if (set_of (reg, insn) != NULL_RTX
17678 && !prologue_epilogue_contains (insn))
17685 /* Emit instructions needed to load the TOC register.
17686 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17687 a constant pool; or for SVR4 -fpic. */
17690 rs6000_emit_load_toc_table (int fromprolog)
17693 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17695 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17698 rtx lab, tmp1, tmp2, got;
17700 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17701 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17703 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17705 got = rs6000_got_sym ();
17706 tmp1 = tmp2 = dest;
17709 tmp1 = gen_reg_rtx (Pmode);
17710 tmp2 = gen_reg_rtx (Pmode);
17712 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17713 emit_move_insn (tmp1,
17714 gen_rtx_REG (Pmode, LR_REGNO));
17715 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17716 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17718 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17720 emit_insn (gen_load_toc_v4_pic_si ());
17721 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17723 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17726 rtx temp0 = (fromprolog
17727 ? gen_rtx_REG (Pmode, 0)
17728 : gen_reg_rtx (Pmode));
17734 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17735 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17737 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17738 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17740 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17741 emit_move_insn (dest,
17742 gen_rtx_REG (Pmode, LR_REGNO));
17743 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17749 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17750 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17751 emit_move_insn (dest,
17752 gen_rtx_REG (Pmode, LR_REGNO));
17753 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17755 emit_insn (gen_addsi3 (dest, temp0, dest));
17757 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17759 /* This is for AIX code running in non-PIC ELF32. */
17762 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17763 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17765 emit_insn (gen_elf_high (dest, realsym));
17766 emit_insn (gen_elf_low (dest, dest, realsym));
17770 gcc_assert (DEFAULT_ABI == ABI_AIX);
17773 emit_insn (gen_load_toc_aix_si (dest));
17775 emit_insn (gen_load_toc_aix_di (dest));
17779 /* Emit instructions to restore the link register after determining where
17780 its value has been stored. */
17783 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17785 rs6000_stack_t *info = rs6000_stack_info ();
17788 operands[0] = source;
17789 operands[1] = scratch;
17791 if (info->lr_save_p)
17793 rtx frame_rtx = stack_pointer_rtx;
17794 HOST_WIDE_INT sp_offset = 0;
17797 if (frame_pointer_needed
17798 || cfun->calls_alloca
17799 || info->total_size > 32767)
17801 tmp = gen_frame_mem (Pmode, frame_rtx);
17802 emit_move_insn (operands[1], tmp);
17803 frame_rtx = operands[1];
17805 else if (info->push_p)
17806 sp_offset = info->total_size;
17808 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17809 tmp = gen_frame_mem (Pmode, tmp);
17810 emit_move_insn (tmp, operands[0]);
17813 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17816 static GTY(()) alias_set_type set = -1;
17819 get_TOC_alias_set (void)
17822 set = new_alias_set ();
17826 /* This returns nonzero if the current function uses the TOC. This is
17827 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17828 is generated by the ABI_V4 load_toc_* patterns. */
17835 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17838 rtx pat = PATTERN (insn);
17841 if (GET_CODE (pat) == PARALLEL)
17842 for (i = 0; i < XVECLEN (pat, 0); i++)
17844 rtx sub = XVECEXP (pat, 0, i);
17845 if (GET_CODE (sub) == USE)
17847 sub = XEXP (sub, 0);
17848 if (GET_CODE (sub) == UNSPEC
17849 && XINT (sub, 1) == UNSPEC_TOC)
17859 create_TOC_reference (rtx symbol)
17861 if (TARGET_DEBUG_ADDR)
17863 if (GET_CODE (symbol) == SYMBOL_REF)
17864 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17868 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17869 GET_RTX_NAME (GET_CODE (symbol)));
17870 debug_rtx (symbol);
17874 if (!can_create_pseudo_p ())
17875 df_set_regs_ever_live (TOC_REGISTER, true);
17876 return gen_rtx_PLUS (Pmode,
17877 gen_rtx_REG (Pmode, TOC_REGISTER),
17878 gen_rtx_CONST (Pmode,
17879 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17882 /* Issue assembly directives that create a reference to the given DWARF
17883 FRAME_TABLE_LABEL from the current function section. */
17885 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17887 fprintf (asm_out_file, "\t.ref %s\n",
17888 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17891 /* If _Unwind_* has been called from within the same module,
17892 toc register is not guaranteed to be saved to 40(1) on function
17893 entry. Save it there in that case. */
17896 rs6000_aix_emit_builtin_unwind_init (void)
17899 rtx stack_top = gen_reg_rtx (Pmode);
17900 rtx opcode_addr = gen_reg_rtx (Pmode);
17901 rtx opcode = gen_reg_rtx (SImode);
17902 rtx tocompare = gen_reg_rtx (SImode);
17903 rtx no_toc_save_needed = gen_label_rtx ();
17905 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17906 emit_move_insn (stack_top, mem);
17908 mem = gen_frame_mem (Pmode,
17909 gen_rtx_PLUS (Pmode, stack_top,
17910 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17911 emit_move_insn (opcode_addr, mem);
17912 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17913 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17914 : 0xE8410028, SImode));
17916 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17917 SImode, NULL_RTX, NULL_RTX,
17918 no_toc_save_needed);
17920 mem = gen_frame_mem (Pmode,
17921 gen_rtx_PLUS (Pmode, stack_top,
17922 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17923 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17924 emit_label (no_toc_save_needed);
17927 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17928 and the change to the stack pointer. */
17931 rs6000_emit_stack_tie (void)
17933 rtx mem = gen_frame_mem (BLKmode,
17934 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17936 emit_insn (gen_stack_tie (mem));
17939 /* Emit the correct code for allocating stack space, as insns.
17940 If COPY_R12, make sure a copy of the old frame is left in r12.
17941 If COPY_R11, make sure a copy of the old frame is left in r11,
17942 in preference to r12 if COPY_R12.
17943 The generated code may use hard register 0 as a temporary. */
17946 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17949 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17950 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17951 rtx todec = gen_int_mode (-size, Pmode);
17954 if (INTVAL (todec) != -size)
17956 warning (0, "stack frame too large");
17957 emit_insn (gen_trap ());
17961 if (crtl->limit_stack)
17963 if (REG_P (stack_limit_rtx)
17964 && REGNO (stack_limit_rtx) > 1
17965 && REGNO (stack_limit_rtx) <= 31)
17967 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
17968 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17971 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17973 && DEFAULT_ABI == ABI_V4)
17975 rtx toload = gen_rtx_CONST (VOIDmode,
17976 gen_rtx_PLUS (Pmode,
17980 emit_insn (gen_elf_high (tmp_reg, toload));
17981 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17982 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17986 warning (0, "stack limit expression is not supported");
17989 if (copy_r12 || copy_r11)
17990 emit_move_insn (copy_r11
17991 ? gen_rtx_REG (Pmode, 11)
17992 : gen_rtx_REG (Pmode, 12),
17997 /* Need a note here so that try_split doesn't get confused. */
17998 if (get_last_insn () == NULL_RTX)
17999 emit_note (NOTE_INSN_DELETED);
18000 insn = emit_move_insn (tmp_reg, todec);
18001 try_split (PATTERN (insn), insn, 0);
18005 insn = emit_insn (TARGET_32BIT
18006 ? gen_movsi_update_stack (stack_reg, stack_reg,
18008 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18009 todec, stack_reg));
18010 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18011 it now and set the alias set/attributes. The above gen_*_update
18012 calls will generate a PARALLEL with the MEM set being the first
18014 par = PATTERN (insn);
18015 gcc_assert (GET_CODE (par) == PARALLEL);
18016 set = XVECEXP (par, 0, 0);
18017 gcc_assert (GET_CODE (set) == SET);
18018 mem = SET_DEST (set);
18019 gcc_assert (MEM_P (mem));
18020 MEM_NOTRAP_P (mem) = 1;
18021 set_mem_alias_set (mem, get_frame_alias_set ());
18023 RTX_FRAME_RELATED_P (insn) = 1;
18024 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18025 gen_rtx_SET (VOIDmode, stack_reg,
18026 gen_rtx_PLUS (Pmode, stack_reg,
18027 GEN_INT (-size))));
18030 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18031 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18032 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18033 deduce these equivalences by itself so it wasn't necessary to hold
18034 its hand so much. */
18037 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18038 rtx reg2, rtx rreg)
18042 /* copy_rtx will not make unique copies of registers, so we need to
18043 ensure we don't have unwanted sharing here. */
18045 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18048 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18050 real = copy_rtx (PATTERN (insn));
18052 if (reg2 != NULL_RTX)
18053 real = replace_rtx (real, reg2, rreg);
18055 real = replace_rtx (real, reg,
18056 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18057 STACK_POINTER_REGNUM),
18060 /* We expect that 'real' is either a SET or a PARALLEL containing
18061 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18062 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18064 if (GET_CODE (real) == SET)
18068 temp = simplify_rtx (SET_SRC (set));
18070 SET_SRC (set) = temp;
18071 temp = simplify_rtx (SET_DEST (set));
18073 SET_DEST (set) = temp;
18074 if (GET_CODE (SET_DEST (set)) == MEM)
18076 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18078 XEXP (SET_DEST (set), 0) = temp;
18085 gcc_assert (GET_CODE (real) == PARALLEL);
18086 for (i = 0; i < XVECLEN (real, 0); i++)
18087 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18089 rtx set = XVECEXP (real, 0, i);
18091 temp = simplify_rtx (SET_SRC (set));
18093 SET_SRC (set) = temp;
18094 temp = simplify_rtx (SET_DEST (set));
18096 SET_DEST (set) = temp;
18097 if (GET_CODE (SET_DEST (set)) == MEM)
18099 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18101 XEXP (SET_DEST (set), 0) = temp;
18103 RTX_FRAME_RELATED_P (set) = 1;
18107 RTX_FRAME_RELATED_P (insn) = 1;
18108 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18111 /* Returns an insn that has a vrsave set operation with the
18112 appropriate CLOBBERs. */
18115 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18118 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18119 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18122 = gen_rtx_SET (VOIDmode,
18124 gen_rtx_UNSPEC_VOLATILE (SImode,
18125 gen_rtvec (2, reg, vrsave),
18126 UNSPECV_SET_VRSAVE));
18130 /* We need to clobber the registers in the mask so the scheduler
18131 does not move sets to VRSAVE before sets of AltiVec registers.
18133 However, if the function receives nonlocal gotos, reload will set
18134 all call saved registers live. We will end up with:
18136 (set (reg 999) (mem))
18137 (parallel [ (set (reg vrsave) (unspec blah))
18138 (clobber (reg 999))])
18140 The clobber will cause the store into reg 999 to be dead, and
18141 flow will attempt to delete an epilogue insn. In this case, we
18142 need an unspec use/set of the register. */
18144 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18145 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18147 if (!epiloguep || call_used_regs [i])
18148 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18149 gen_rtx_REG (V4SImode, i));
18152 rtx reg = gen_rtx_REG (V4SImode, i);
18155 = gen_rtx_SET (VOIDmode,
18157 gen_rtx_UNSPEC (V4SImode,
18158 gen_rtvec (1, reg), 27));
18162 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18164 for (i = 0; i < nclobs; ++i)
18165 XVECEXP (insn, 0, i) = clobs[i];
18170 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18171 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18174 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18175 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18177 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18178 rtx replacea, replaceb;
18180 int_rtx = GEN_INT (offset);
18182 /* Some cases that need register indexed addressing. */
18183 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18184 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18185 || (TARGET_E500_DOUBLE && mode == DFmode)
18187 && SPE_VECTOR_MODE (mode)
18188 && !SPE_CONST_OFFSET_OK (offset)))
18190 /* Whomever calls us must make sure r11 is available in the
18191 flow path of instructions in the prologue. */
18192 offset_rtx = gen_rtx_REG (Pmode, 11);
18193 emit_move_insn (offset_rtx, int_rtx);
18195 replacea = offset_rtx;
18196 replaceb = int_rtx;
18200 offset_rtx = int_rtx;
18201 replacea = NULL_RTX;
18202 replaceb = NULL_RTX;
18205 reg = gen_rtx_REG (mode, regno);
18206 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18207 mem = gen_frame_mem (mode, addr);
18209 insn = emit_move_insn (mem, reg);
18211 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18214 /* Emit an offset memory reference suitable for a frame store, while
18215 converting to a valid addressing mode. */
18218 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18220 rtx int_rtx, offset_rtx;
18222 int_rtx = GEN_INT (offset);
18224 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18225 || (TARGET_E500_DOUBLE && mode == DFmode))
18227 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18228 emit_move_insn (offset_rtx, int_rtx);
18231 offset_rtx = int_rtx;
18233 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18236 /* Look for user-defined global regs. We should not save and restore these,
18237 and cannot use stmw/lmw if there are any in its range. */
18240 no_global_regs_above (int first, bool gpr)
18243 int last = gpr ? 32 : 64;
18244 for (i = first; i < last; i++)
18245 if (global_regs[i])
18250 #ifndef TARGET_FIX_AND_CONTINUE
18251 #define TARGET_FIX_AND_CONTINUE 0
18254 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18255 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18256 #define LAST_SAVRES_REGISTER 31
18257 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18259 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18261 /* Temporary holding space for an out-of-line register save/restore
18263 static char savres_routine_name[30];
18265 /* Return the name for an out-of-line register save/restore routine.
18266 We are saving/restoring GPRs if GPR is true. */
18269 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18270 bool savep, bool gpr, bool lr)
18272 const char *prefix = "";
18273 const char *suffix = "";
18275 /* Different targets are supposed to define
18276 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18277 routine name could be defined with:
18279 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18281 This is a nice idea in practice, but in reality, things are
18282 complicated in several ways:
18284 - ELF targets have save/restore routines for GPRs.
18286 - SPE targets use different prefixes for 32/64-bit registers, and
18287 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18289 - PPC64 ELF targets have routines for save/restore of GPRs that
18290 differ in what they do with the link register, so having a set
18291 prefix doesn't work. (We only use one of the save routines at
18292 the moment, though.)
18294 - PPC32 elf targets have "exit" versions of the restore routines
18295 that restore the link register and can save some extra space.
18296 These require an extra suffix. (There are also "tail" versions
18297 of the restore routines and "GOT" versions of the save routines,
18298 but we don't generate those at present. Same problems apply,
18301 We deal with all this by synthesizing our own prefix/suffix and
18302 using that for the simple sprintf call shown above. */
18305 /* No floating point saves on the SPE. */
18309 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18311 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18316 else if (DEFAULT_ABI == ABI_V4)
18322 prefix = savep ? "_savegpr_" : "_restgpr_";
18324 prefix = savep ? "_savefpr_" : "_restfpr_";
18329 else if (DEFAULT_ABI == ABI_AIX)
18331 #ifndef POWERPC_LINUX
18332 /* No out-of-line save/restore routines for GPRs on AIX. */
18333 gcc_assert (!TARGET_AIX || !gpr);
18339 ? (lr ? "_savegpr0_" : "_savegpr1_")
18340 : (lr ? "_restgpr0_" : "_restgpr1_"));
18341 #ifdef POWERPC_LINUX
18343 prefix = (savep ? "_savefpr_" : "_restfpr_");
18347 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18348 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18351 else if (DEFAULT_ABI == ABI_DARWIN)
18352 sorry ("Out-of-line save/restore routines not supported on Darwin");
18354 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18356 return savres_routine_name;
18359 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18360 We are saving/restoring GPRs if GPR is true. */
18363 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18366 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18368 int select = ((savep ? 1 : 0) << 2
18370 /* On the SPE, we never have any FPRs, but we do have
18371 32/64-bit versions of the routines. */
18372 ? (info->spe_64bit_regs_used ? 1 : 0)
18373 : (gpr ? 1 : 0)) << 1)
18376 /* Don't generate bogus routine names. */
18377 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18378 && regno <= LAST_SAVRES_REGISTER);
18380 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18386 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18388 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18389 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18390 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18396 /* Emit a sequence of insns, including a stack tie if needed, for
18397 resetting the stack pointer. If SAVRES is true, then don't reset the
18398 stack pointer, but move the base of the frame into r11 for use by
18399 out-of-line register restore routines. */
18402 rs6000_emit_stack_reset (rs6000_stack_t *info,
18403 rtx sp_reg_rtx, rtx frame_reg_rtx,
18404 int sp_offset, bool savres)
18406 /* This blockage is needed so that sched doesn't decide to move
18407 the sp change before the register restores. */
18408 if (frame_reg_rtx != sp_reg_rtx
18410 && info->spe_64bit_regs_used != 0
18411 && info->first_gp_reg_save != 32))
18412 rs6000_emit_stack_tie ();
18414 if (frame_reg_rtx != sp_reg_rtx)
18416 if (sp_offset != 0)
18418 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18419 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18420 GEN_INT (sp_offset)));
18423 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18425 else if (sp_offset != 0)
18427 /* If we are restoring registers out-of-line, we will be using the
18428 "exit" variants of the restore routines, which will reset the
18429 stack for us. But we do need to point r11 into the right place
18430 for those routines. */
18431 rtx dest_reg = (savres
18432 ? gen_rtx_REG (Pmode, 11)
18435 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18436 GEN_INT (sp_offset)));
18443 /* Construct a parallel rtx describing the effect of a call to an
18444 out-of-line register save/restore routine. */
18447 rs6000_make_savres_rtx (rs6000_stack_t *info,
18448 rtx frame_reg_rtx, int save_area_offset,
18449 enum machine_mode reg_mode,
18450 bool savep, bool gpr, bool lr)
18453 int offset, start_reg, end_reg, n_regs;
18454 int reg_size = GET_MODE_SIZE (reg_mode);
18460 ? info->first_gp_reg_save
18461 : info->first_fp_reg_save);
18462 end_reg = gpr ? 32 : 64;
18463 n_regs = end_reg - start_reg;
18464 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18467 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18469 RTVEC_ELT (p, offset++)
18470 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18472 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18473 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18474 RTVEC_ELT (p, offset++)
18475 = gen_rtx_USE (VOIDmode,
18476 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18480 for (i = 0; i < end_reg - start_reg; i++)
18482 rtx addr, reg, mem;
18483 reg = gen_rtx_REG (reg_mode, start_reg + i);
18484 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18485 GEN_INT (save_area_offset + reg_size*i));
18486 mem = gen_frame_mem (reg_mode, addr);
18488 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18490 savep ? reg : mem);
18495 rtx addr, reg, mem;
18496 reg = gen_rtx_REG (Pmode, 0);
18497 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18498 GEN_INT (info->lr_save_offset));
18499 mem = gen_frame_mem (Pmode, addr);
18500 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18503 return gen_rtx_PARALLEL (VOIDmode, p);
18506 /* Determine whether the gp REG is really used. */
18509 rs6000_reg_live_or_pic_offset_p (int reg)
18511 return ((df_regs_ever_live_p (reg)
18512 && (!call_used_regs[reg]
18513 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18514 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18515 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18516 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18517 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18521 SAVRES_MULTIPLE = 0x1,
18522 SAVRES_INLINE_FPRS = 0x2,
18523 SAVRES_INLINE_GPRS = 0x4,
18524 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18525 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18526 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18529 /* Determine the strategy for savings/restoring registers. */
18532 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18533 int using_static_chain_p, int sibcall)
18535 bool using_multiple_p;
18537 bool savres_fprs_inline;
18538 bool savres_gprs_inline;
18539 bool noclobber_global_gprs
18540 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18543 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18544 && (!TARGET_SPE_ABI
18545 || info->spe_64bit_regs_used == 0)
18546 && info->first_gp_reg_save < 31
18547 && noclobber_global_gprs);
18548 /* Don't bother to try to save things out-of-line if r11 is occupied
18549 by the static chain. It would require too much fiddling and the
18550 static chain is rarely used anyway. */
18551 common = (using_static_chain_p
18553 || crtl->calls_eh_return
18554 || !info->lr_save_p
18555 || cfun->machine->ra_need_lr
18556 || info->total_size > 32767);
18557 savres_fprs_inline = (common
18558 || info->first_fp_reg_save == 64
18559 || !no_global_regs_above (info->first_fp_reg_save,
18561 /* The out-of-line FP routines use
18562 double-precision stores; we can't use those
18563 routines if we don't have such stores. */
18564 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18565 || FP_SAVE_INLINE (info->first_fp_reg_save));
18566 savres_gprs_inline = (common
18567 /* Saving CR interferes with the exit routines
18568 used on the SPE, so just punt here. */
18571 && info->spe_64bit_regs_used != 0
18572 && info->cr_save_p != 0)
18573 || info->first_gp_reg_save == 32
18574 || !noclobber_global_gprs
18575 || GP_SAVE_INLINE (info->first_gp_reg_save));
18578 /* If we are going to use store multiple, then don't even bother
18579 with the out-of-line routines, since the store-multiple instruction
18580 will always be smaller. */
18581 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18584 /* The situation is more complicated with load multiple. We'd
18585 prefer to use the out-of-line routines for restores, since the
18586 "exit" out-of-line routines can handle the restore of LR and
18587 the frame teardown. But we can only use the out-of-line
18588 routines if we know that we've used store multiple or
18589 out-of-line routines in the prologue, i.e. if we've saved all
18590 the registers from first_gp_reg_save. Otherwise, we risk
18591 loading garbage from the stack. Furthermore, we can only use
18592 the "exit" out-of-line gpr restore if we haven't saved any
18594 bool saved_all = !savres_gprs_inline || using_multiple_p;
18596 if (saved_all && info->first_fp_reg_save != 64)
18597 /* We can't use the exit routine; use load multiple if it's
18599 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18602 strategy = (using_multiple_p
18603 | (savres_fprs_inline << 1)
18604 | (savres_gprs_inline << 2));
18605 #ifdef POWERPC_LINUX
18608 if (!savres_fprs_inline)
18609 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18610 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18611 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18614 if (TARGET_AIX && !savres_fprs_inline)
18615 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18620 /* Emit function prologue as insns. */
18623 rs6000_emit_prologue (void)
18625 rs6000_stack_t *info = rs6000_stack_info ();
18626 enum machine_mode reg_mode = Pmode;
18627 int reg_size = TARGET_32BIT ? 4 : 8;
18628 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18629 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18630 rtx frame_reg_rtx = sp_reg_rtx;
18631 rtx cr_save_rtx = NULL_RTX;
18634 int saving_FPRs_inline;
18635 int saving_GPRs_inline;
18636 int using_store_multiple;
18637 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18638 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18639 && call_used_regs[STATIC_CHAIN_REGNUM]);
18640 HOST_WIDE_INT sp_offset = 0;
18642 if (TARGET_FIX_AND_CONTINUE)
18644 /* gdb on darwin arranges to forward a function from the old
18645 address by modifying the first 5 instructions of the function
18646 to branch to the overriding function. This is necessary to
18647 permit function pointers that point to the old function to
18648 actually forward to the new function. */
18649 emit_insn (gen_nop ());
18650 emit_insn (gen_nop ());
18651 emit_insn (gen_nop ());
18652 emit_insn (gen_nop ());
18653 emit_insn (gen_nop ());
18656 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18658 reg_mode = V2SImode;
18662 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18663 /*static_chain_p=*/using_static_chain_p,
18665 using_store_multiple = strategy & SAVRES_MULTIPLE;
18666 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18667 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18669 /* For V.4, update stack before we do any saving and set back pointer. */
18670 if (! WORLD_SAVE_P (info)
18672 && (DEFAULT_ABI == ABI_V4
18673 || crtl->calls_eh_return))
18675 bool need_r11 = (TARGET_SPE
18676 ? (!saving_GPRs_inline
18677 && info->spe_64bit_regs_used == 0)
18678 : (!saving_FPRs_inline || !saving_GPRs_inline));
18679 if (info->total_size < 32767)
18680 sp_offset = info->total_size;
18682 frame_reg_rtx = (need_r11
18683 ? gen_rtx_REG (Pmode, 11)
18685 rs6000_emit_allocate_stack (info->total_size,
18686 (frame_reg_rtx != sp_reg_rtx
18687 && (info->cr_save_p
18689 || info->first_fp_reg_save < 64
18690 || info->first_gp_reg_save < 32
18693 if (frame_reg_rtx != sp_reg_rtx)
18694 rs6000_emit_stack_tie ();
18697 /* Handle world saves specially here. */
18698 if (WORLD_SAVE_P (info))
18705 /* save_world expects lr in r0. */
18706 reg0 = gen_rtx_REG (Pmode, 0);
18707 if (info->lr_save_p)
18709 insn = emit_move_insn (reg0,
18710 gen_rtx_REG (Pmode, LR_REGNO));
18711 RTX_FRAME_RELATED_P (insn) = 1;
18714 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18715 assumptions about the offsets of various bits of the stack
18717 gcc_assert (info->gp_save_offset == -220
18718 && info->fp_save_offset == -144
18719 && info->lr_save_offset == 8
18720 && info->cr_save_offset == 4
18723 && (!crtl->calls_eh_return
18724 || info->ehrd_offset == -432)
18725 && info->vrsave_save_offset == -224
18726 && info->altivec_save_offset == -416);
18728 treg = gen_rtx_REG (SImode, 11);
18729 emit_move_insn (treg, GEN_INT (-info->total_size));
18731 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18732 in R11. It also clobbers R12, so beware! */
18734 /* Preserve CR2 for save_world prologues */
18736 sz += 32 - info->first_gp_reg_save;
18737 sz += 64 - info->first_fp_reg_save;
18738 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18739 p = rtvec_alloc (sz);
18741 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18742 gen_rtx_REG (SImode,
18744 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18745 gen_rtx_SYMBOL_REF (Pmode,
18747 /* We do floats first so that the instruction pattern matches
18749 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18751 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18752 ? DFmode : SFmode),
18753 info->first_fp_reg_save + i);
18754 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18755 GEN_INT (info->fp_save_offset
18756 + sp_offset + 8 * i));
18757 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18758 ? DFmode : SFmode), addr);
18760 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18762 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18764 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18765 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18766 GEN_INT (info->altivec_save_offset
18767 + sp_offset + 16 * i));
18768 rtx mem = gen_frame_mem (V4SImode, addr);
18770 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18772 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18774 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18775 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18776 GEN_INT (info->gp_save_offset
18777 + sp_offset + reg_size * i));
18778 rtx mem = gen_frame_mem (reg_mode, addr);
18780 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18784 /* CR register traditionally saved as CR2. */
18785 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18786 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18787 GEN_INT (info->cr_save_offset
18789 rtx mem = gen_frame_mem (reg_mode, addr);
18791 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18793 /* Explain about use of R0. */
18794 if (info->lr_save_p)
18796 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18797 GEN_INT (info->lr_save_offset
18799 rtx mem = gen_frame_mem (reg_mode, addr);
18801 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18803 /* Explain what happens to the stack pointer. */
18805 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18806 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18809 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18810 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18811 treg, GEN_INT (-info->total_size));
18812 sp_offset = info->total_size;
18815 /* If we use the link register, get it into r0. */
18816 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18818 rtx addr, reg, mem;
18820 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18821 gen_rtx_REG (Pmode, LR_REGNO));
18822 RTX_FRAME_RELATED_P (insn) = 1;
18824 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18825 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18827 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18828 GEN_INT (info->lr_save_offset + sp_offset));
18829 reg = gen_rtx_REG (Pmode, 0);
18830 mem = gen_rtx_MEM (Pmode, addr);
18831 /* This should not be of rs6000_sr_alias_set, because of
18832 __builtin_return_address. */
18834 insn = emit_move_insn (mem, reg);
18835 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18836 NULL_RTX, NULL_RTX);
18840 /* If we need to save CR, put it into r12 or r11. */
18841 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18846 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18848 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18849 RTX_FRAME_RELATED_P (insn) = 1;
18850 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18851 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18852 But that's OK. All we have to do is specify that _one_ condition
18853 code register is saved in this stack slot. The thrower's epilogue
18854 will then restore all the call-saved registers.
18855 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18856 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18857 gen_rtx_REG (SImode, CR2_REGNO));
18858 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18861 /* Do any required saving of fpr's. If only one or two to save, do
18862 it ourselves. Otherwise, call function. */
18863 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18866 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18867 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18868 && ! call_used_regs[info->first_fp_reg_save+i]))
18869 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18870 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18872 info->first_fp_reg_save + i,
18873 info->fp_save_offset + sp_offset + 8 * i,
18876 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18880 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18881 info->fp_save_offset + sp_offset,
18883 /*savep=*/true, /*gpr=*/false,
18885 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18887 insn = emit_insn (par);
18888 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18889 NULL_RTX, NULL_RTX);
18892 /* Save GPRs. This is done as a PARALLEL if we are using
18893 the store-multiple instructions. */
18894 if (!WORLD_SAVE_P (info)
18896 && info->spe_64bit_regs_used != 0
18897 && info->first_gp_reg_save != 32)
18900 rtx spe_save_area_ptr;
18902 /* Determine whether we can address all of the registers that need
18903 to be saved with an offset from the stack pointer that fits in
18904 the small const field for SPE memory instructions. */
18905 int spe_regs_addressable_via_sp
18906 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18907 + (32 - info->first_gp_reg_save - 1) * reg_size)
18908 && saving_GPRs_inline);
18911 if (spe_regs_addressable_via_sp)
18913 spe_save_area_ptr = frame_reg_rtx;
18914 spe_offset = info->spe_gp_save_offset + sp_offset;
18918 /* Make r11 point to the start of the SPE save area. We need
18919 to be careful here if r11 is holding the static chain. If
18920 it is, then temporarily save it in r0. We would use r0 as
18921 our base register here, but using r0 as a base register in
18922 loads and stores means something different from what we
18924 int ool_adjust = (saving_GPRs_inline
18926 : (info->first_gp_reg_save
18927 - (FIRST_SAVRES_REGISTER+1))*8);
18928 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18929 + sp_offset - ool_adjust);
18931 if (using_static_chain_p)
18933 rtx r0 = gen_rtx_REG (Pmode, 0);
18934 gcc_assert (info->first_gp_reg_save > 11);
18936 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18939 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18940 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18942 GEN_INT (offset)));
18943 /* We need to make sure the move to r11 gets noted for
18944 properly outputting unwind information. */
18945 if (!saving_GPRs_inline)
18946 rs6000_frame_related (insn, frame_reg_rtx, offset,
18947 NULL_RTX, NULL_RTX);
18951 if (saving_GPRs_inline)
18953 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18954 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18956 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18957 rtx offset, addr, mem;
18959 /* We're doing all this to ensure that the offset fits into
18960 the immediate offset of 'evstdd'. */
18961 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18963 offset = GEN_INT (reg_size * i + spe_offset);
18964 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18965 mem = gen_rtx_MEM (V2SImode, addr);
18967 insn = emit_move_insn (mem, reg);
18969 rs6000_frame_related (insn, spe_save_area_ptr,
18970 info->spe_gp_save_offset
18971 + sp_offset + reg_size * i,
18972 offset, const0_rtx);
18979 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18981 /*savep=*/true, /*gpr=*/true,
18983 insn = emit_insn (par);
18984 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18985 NULL_RTX, NULL_RTX);
18989 /* Move the static chain pointer back. */
18990 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18991 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18993 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18997 /* Need to adjust r11 (r12) if we saved any FPRs. */
18998 if (info->first_fp_reg_save != 64)
19000 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19002 rtx offset = GEN_INT (sp_offset
19003 + (-8 * (64-info->first_fp_reg_save)));
19004 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19007 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19008 info->gp_save_offset + sp_offset,
19010 /*savep=*/true, /*gpr=*/true,
19012 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19014 insn = emit_insn (par);
19015 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19016 NULL_RTX, NULL_RTX);
19018 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19022 p = rtvec_alloc (32 - info->first_gp_reg_save);
19023 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19025 rtx addr, reg, mem;
19026 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19027 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19028 GEN_INT (info->gp_save_offset
19031 mem = gen_frame_mem (reg_mode, addr);
19033 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19035 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19036 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19037 NULL_RTX, NULL_RTX);
19039 else if (!WORLD_SAVE_P (info))
19042 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19043 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19045 rtx addr, reg, mem;
19046 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19048 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19049 GEN_INT (info->gp_save_offset
19052 mem = gen_frame_mem (reg_mode, addr);
19054 insn = emit_move_insn (mem, reg);
19055 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19056 NULL_RTX, NULL_RTX);
19060 /* ??? There's no need to emit actual instructions here, but it's the
19061 easiest way to get the frame unwind information emitted. */
19062 if (crtl->calls_eh_return)
19064 unsigned int i, regno;
19066 /* In AIX ABI we need to pretend we save r2 here. */
19069 rtx addr, reg, mem;
19071 reg = gen_rtx_REG (reg_mode, 2);
19072 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19073 GEN_INT (sp_offset + 5 * reg_size));
19074 mem = gen_frame_mem (reg_mode, addr);
19076 insn = emit_move_insn (mem, reg);
19077 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19078 NULL_RTX, NULL_RTX);
19079 PATTERN (insn) = gen_blockage ();
19084 regno = EH_RETURN_DATA_REGNO (i);
19085 if (regno == INVALID_REGNUM)
19088 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19089 info->ehrd_offset + sp_offset
19090 + reg_size * (int) i,
19095 /* Save CR if we use any that must be preserved. */
19096 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19098 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19099 GEN_INT (info->cr_save_offset + sp_offset));
19100 rtx mem = gen_frame_mem (SImode, addr);
19101 /* See the large comment above about why CR2_REGNO is used. */
19102 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19104 /* If r12 was used to hold the original sp, copy cr into r0 now
19106 if (REGNO (frame_reg_rtx) == 12)
19110 cr_save_rtx = gen_rtx_REG (SImode, 0);
19111 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19112 RTX_FRAME_RELATED_P (insn) = 1;
19113 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19114 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19116 insn = emit_move_insn (mem, cr_save_rtx);
19118 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19119 NULL_RTX, NULL_RTX);
19122 /* Update stack and set back pointer unless this is V.4,
19123 for which it was done previously. */
19124 if (!WORLD_SAVE_P (info) && info->push_p
19125 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19127 if (info->total_size < 32767)
19128 sp_offset = info->total_size;
19130 frame_reg_rtx = frame_ptr_rtx;
19131 rs6000_emit_allocate_stack (info->total_size,
19132 (frame_reg_rtx != sp_reg_rtx
19133 && ((info->altivec_size != 0)
19134 || (info->vrsave_mask != 0)
19137 if (frame_reg_rtx != sp_reg_rtx)
19138 rs6000_emit_stack_tie ();
19141 /* Set frame pointer, if needed. */
19142 if (frame_pointer_needed)
19144 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19146 RTX_FRAME_RELATED_P (insn) = 1;
19149 /* Save AltiVec registers if needed. Save here because the red zone does
19150 not include AltiVec registers. */
19151 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19155 /* There should be a non inline version of this, for when we
19156 are saving lots of vector registers. */
19157 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19158 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19160 rtx areg, savereg, mem;
19163 offset = info->altivec_save_offset + sp_offset
19164 + 16 * (i - info->first_altivec_reg_save);
19166 savereg = gen_rtx_REG (V4SImode, i);
19168 areg = gen_rtx_REG (Pmode, 0);
19169 emit_move_insn (areg, GEN_INT (offset));
19171 /* AltiVec addressing mode is [reg+reg]. */
19172 mem = gen_frame_mem (V4SImode,
19173 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19175 insn = emit_move_insn (mem, savereg);
19177 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19178 areg, GEN_INT (offset));
19182 /* VRSAVE is a bit vector representing which AltiVec registers
19183 are used. The OS uses this to determine which vector
19184 registers to save on a context switch. We need to save
19185 VRSAVE on the stack frame, add whatever AltiVec registers we
19186 used in this function, and do the corresponding magic in the
19189 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19190 && info->vrsave_mask != 0)
19192 rtx reg, mem, vrsave;
19195 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19196 as frame_reg_rtx and r11 as the static chain pointer for
19197 nested functions. */
19198 reg = gen_rtx_REG (SImode, 0);
19199 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19201 emit_insn (gen_get_vrsave_internal (reg));
19203 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19205 if (!WORLD_SAVE_P (info))
19208 offset = info->vrsave_save_offset + sp_offset;
19209 mem = gen_frame_mem (SImode,
19210 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19211 GEN_INT (offset)));
19212 insn = emit_move_insn (mem, reg);
19215 /* Include the registers in the mask. */
19216 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19218 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19221 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19222 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19223 || (DEFAULT_ABI == ABI_V4
19224 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19225 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19227 /* If emit_load_toc_table will use the link register, we need to save
19228 it. We use R12 for this purpose because emit_load_toc_table
19229 can use register 0. This allows us to use a plain 'blr' to return
19230 from the procedure more often. */
19231 int save_LR_around_toc_setup = (TARGET_ELF
19232 && DEFAULT_ABI != ABI_AIX
19234 && ! info->lr_save_p
19235 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19236 if (save_LR_around_toc_setup)
19238 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19240 insn = emit_move_insn (frame_ptr_rtx, lr);
19241 RTX_FRAME_RELATED_P (insn) = 1;
19243 rs6000_emit_load_toc_table (TRUE);
19245 insn = emit_move_insn (lr, frame_ptr_rtx);
19246 RTX_FRAME_RELATED_P (insn) = 1;
19249 rs6000_emit_load_toc_table (TRUE);
19253 if (DEFAULT_ABI == ABI_DARWIN
19254 && flag_pic && crtl->uses_pic_offset_table)
19256 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19257 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19259 /* Save and restore LR locally around this call (in R0). */
19260 if (!info->lr_save_p)
19261 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19263 emit_insn (gen_load_macho_picbase (src));
19265 emit_move_insn (gen_rtx_REG (Pmode,
19266 RS6000_PIC_OFFSET_TABLE_REGNUM),
19269 if (!info->lr_save_p)
19270 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19275 /* Write function prologue. */
19278 rs6000_output_function_prologue (FILE *file,
19279 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19281 rs6000_stack_t *info = rs6000_stack_info ();
19283 if (TARGET_DEBUG_STACK)
19284 debug_stack_info (info);
19286 /* Write .extern for any function we will call to save and restore
19288 if (info->first_fp_reg_save < 64
19289 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19292 int regno = info->first_fp_reg_save - 32;
19294 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19295 /*gpr=*/false, /*lr=*/false);
19296 fprintf (file, "\t.extern %s\n", name);
19298 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19299 /*gpr=*/false, /*lr=*/true);
19300 fprintf (file, "\t.extern %s\n", name);
19303 /* Write .extern for AIX common mode routines, if needed. */
19304 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19306 fputs ("\t.extern __mulh\n", file);
19307 fputs ("\t.extern __mull\n", file);
19308 fputs ("\t.extern __divss\n", file);
19309 fputs ("\t.extern __divus\n", file);
19310 fputs ("\t.extern __quoss\n", file);
19311 fputs ("\t.extern __quous\n", file);
19312 common_mode_defined = 1;
19315 if (! HAVE_prologue)
19321 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19322 the "toplevel" insn chain. */
19323 emit_note (NOTE_INSN_DELETED);
19324 rs6000_emit_prologue ();
19325 emit_note (NOTE_INSN_DELETED);
19327 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19331 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19333 INSN_ADDRESSES_NEW (insn, addr);
19338 prologue = get_insns ();
19341 if (TARGET_DEBUG_STACK)
19342 debug_rtx_list (prologue, 100);
19344 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19348 rs6000_pic_labelno++;
19351 /* Non-zero if vmx regs are restored before the frame pop, zero if
19352 we restore after the pop when possible. */
19353 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19355 /* Reload CR from REG. */
19358 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19363 if (using_mfcr_multiple)
19365 for (i = 0; i < 8; i++)
19366 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19368 gcc_assert (count);
19371 if (using_mfcr_multiple && count > 1)
19376 p = rtvec_alloc (count);
19379 for (i = 0; i < 8; i++)
19380 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19382 rtvec r = rtvec_alloc (2);
19383 RTVEC_ELT (r, 0) = reg;
19384 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19385 RTVEC_ELT (p, ndx) =
19386 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19387 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19390 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19391 gcc_assert (ndx == count);
19394 for (i = 0; i < 8; i++)
19395 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19397 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19403 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19404 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19405 below stack pointer not cloberred by signals. */
19408 offset_below_red_zone_p (HOST_WIDE_INT offset)
19410 return offset < (DEFAULT_ABI == ABI_V4
19412 : TARGET_32BIT ? -220 : -288);
19415 /* Emit function epilogue as insns. */
19418 rs6000_emit_epilogue (int sibcall)
19420 rs6000_stack_t *info;
19421 int restoring_GPRs_inline;
19422 int restoring_FPRs_inline;
19423 int using_load_multiple;
19424 int using_mtcr_multiple;
19425 int use_backchain_to_restore_sp;
19429 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19430 rtx frame_reg_rtx = sp_reg_rtx;
19431 rtx cfa_restores = NULL_RTX;
19433 rtx cr_save_reg = NULL_RTX;
19434 enum machine_mode reg_mode = Pmode;
19435 int reg_size = TARGET_32BIT ? 4 : 8;
19438 info = rs6000_stack_info ();
19440 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19442 reg_mode = V2SImode;
19446 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19447 /*static_chain_p=*/0, sibcall);
19448 using_load_multiple = strategy & SAVRES_MULTIPLE;
19449 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19450 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19451 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19452 || rs6000_cpu == PROCESSOR_PPC603
19453 || rs6000_cpu == PROCESSOR_PPC750
19455 /* Restore via the backchain when we have a large frame, since this
19456 is more efficient than an addis, addi pair. The second condition
19457 here will not trigger at the moment; We don't actually need a
19458 frame pointer for alloca, but the generic parts of the compiler
19459 give us one anyway. */
19460 use_backchain_to_restore_sp = (info->total_size > 32767
19461 || info->total_size
19462 + (info->lr_save_p ? info->lr_save_offset : 0)
19464 || (cfun->calls_alloca
19465 && !frame_pointer_needed));
19466 restore_lr = (info->lr_save_p
19467 && (restoring_FPRs_inline
19468 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19469 && (restoring_GPRs_inline
19470 || info->first_fp_reg_save < 64));
19472 if (WORLD_SAVE_P (info))
19476 const char *alloc_rname;
19479 /* eh_rest_world_r10 will return to the location saved in the LR
19480 stack slot (which is not likely to be our caller.)
19481 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19482 rest_world is similar, except any R10 parameter is ignored.
19483 The exception-handling stuff that was here in 2.95 is no
19484 longer necessary. */
19488 + 32 - info->first_gp_reg_save
19489 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19490 + 63 + 1 - info->first_fp_reg_save);
19492 strcpy (rname, ((crtl->calls_eh_return) ?
19493 "*eh_rest_world_r10" : "*rest_world"));
19494 alloc_rname = ggc_strdup (rname);
19497 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19498 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19499 gen_rtx_REG (Pmode,
19502 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19503 /* The instruction pattern requires a clobber here;
19504 it is shared with the restVEC helper. */
19506 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19509 /* CR register traditionally saved as CR2. */
19510 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19511 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19512 GEN_INT (info->cr_save_offset));
19513 rtx mem = gen_frame_mem (reg_mode, addr);
19515 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19518 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19520 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19521 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19522 GEN_INT (info->gp_save_offset
19524 rtx mem = gen_frame_mem (reg_mode, addr);
19526 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19528 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19530 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19531 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19532 GEN_INT (info->altivec_save_offset
19534 rtx mem = gen_frame_mem (V4SImode, addr);
19536 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19538 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19540 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19541 ? DFmode : SFmode),
19542 info->first_fp_reg_save + i);
19543 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19544 GEN_INT (info->fp_save_offset
19546 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19547 ? DFmode : SFmode), addr);
19549 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19552 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19554 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19556 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19558 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19560 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19561 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19566 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19568 sp_offset = info->total_size;
19570 /* Restore AltiVec registers if we must do so before adjusting the
19572 if (TARGET_ALTIVEC_ABI
19573 && info->altivec_size != 0
19574 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19575 || (DEFAULT_ABI != ABI_V4
19576 && offset_below_red_zone_p (info->altivec_save_offset))))
19580 if (use_backchain_to_restore_sp)
19582 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19583 emit_move_insn (frame_reg_rtx,
19584 gen_rtx_MEM (Pmode, sp_reg_rtx));
19587 else if (frame_pointer_needed)
19588 frame_reg_rtx = hard_frame_pointer_rtx;
19590 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19591 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19593 rtx addr, areg, mem, reg;
19595 areg = gen_rtx_REG (Pmode, 0);
19597 (areg, GEN_INT (info->altivec_save_offset
19599 + 16 * (i - info->first_altivec_reg_save)));
19601 /* AltiVec addressing mode is [reg+reg]. */
19602 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19603 mem = gen_frame_mem (V4SImode, addr);
19605 reg = gen_rtx_REG (V4SImode, i);
19606 emit_move_insn (reg, mem);
19607 if (offset_below_red_zone_p (info->altivec_save_offset
19608 + (i - info->first_altivec_reg_save)
19610 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19615 /* Restore VRSAVE if we must do so before adjusting the stack. */
19617 && TARGET_ALTIVEC_VRSAVE
19618 && info->vrsave_mask != 0
19619 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19620 || (DEFAULT_ABI != ABI_V4
19621 && offset_below_red_zone_p (info->vrsave_save_offset))))
19623 rtx addr, mem, reg;
19625 if (frame_reg_rtx == sp_reg_rtx)
19627 if (use_backchain_to_restore_sp)
19629 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19630 emit_move_insn (frame_reg_rtx,
19631 gen_rtx_MEM (Pmode, sp_reg_rtx));
19634 else if (frame_pointer_needed)
19635 frame_reg_rtx = hard_frame_pointer_rtx;
19638 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19639 GEN_INT (info->vrsave_save_offset + sp_offset));
19640 mem = gen_frame_mem (SImode, addr);
19641 reg = gen_rtx_REG (SImode, 12);
19642 emit_move_insn (reg, mem);
19644 emit_insn (generate_set_vrsave (reg, info, 1));
19648 /* If we have a large stack frame, restore the old stack pointer
19649 using the backchain. */
19650 if (use_backchain_to_restore_sp)
19652 if (frame_reg_rtx == sp_reg_rtx)
19654 /* Under V.4, don't reset the stack pointer until after we're done
19655 loading the saved registers. */
19656 if (DEFAULT_ABI == ABI_V4)
19657 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19659 insn = emit_move_insn (frame_reg_rtx,
19660 gen_rtx_MEM (Pmode, sp_reg_rtx));
19663 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19664 && DEFAULT_ABI == ABI_V4)
19665 /* frame_reg_rtx has been set up by the altivec restore. */
19669 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19670 frame_reg_rtx = sp_reg_rtx;
19673 /* If we have a frame pointer, we can restore the old stack pointer
19675 else if (frame_pointer_needed)
19677 frame_reg_rtx = sp_reg_rtx;
19678 if (DEFAULT_ABI == ABI_V4)
19679 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19681 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19682 GEN_INT (info->total_size)));
19685 else if (info->push_p
19686 && DEFAULT_ABI != ABI_V4
19687 && !crtl->calls_eh_return)
19689 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19690 GEN_INT (info->total_size)));
19693 if (insn && frame_reg_rtx == sp_reg_rtx)
19697 REG_NOTES (insn) = cfa_restores;
19698 cfa_restores = NULL_RTX;
19700 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19701 RTX_FRAME_RELATED_P (insn) = 1;
19704 /* Restore AltiVec registers if we have not done so already. */
19705 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19706 && TARGET_ALTIVEC_ABI
19707 && info->altivec_size != 0
19708 && (DEFAULT_ABI == ABI_V4
19709 || !offset_below_red_zone_p (info->altivec_save_offset)))
19713 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19714 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19716 rtx addr, areg, mem, reg;
19718 areg = gen_rtx_REG (Pmode, 0);
19720 (areg, GEN_INT (info->altivec_save_offset
19722 + 16 * (i - info->first_altivec_reg_save)));
19724 /* AltiVec addressing mode is [reg+reg]. */
19725 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19726 mem = gen_frame_mem (V4SImode, addr);
19728 reg = gen_rtx_REG (V4SImode, i);
19729 emit_move_insn (reg, mem);
19730 if (DEFAULT_ABI == ABI_V4)
19731 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19736 /* Restore VRSAVE if we have not done so already. */
19737 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19739 && TARGET_ALTIVEC_VRSAVE
19740 && info->vrsave_mask != 0
19741 && (DEFAULT_ABI == ABI_V4
19742 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19744 rtx addr, mem, reg;
19746 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19747 GEN_INT (info->vrsave_save_offset + sp_offset));
19748 mem = gen_frame_mem (SImode, addr);
19749 reg = gen_rtx_REG (SImode, 12);
19750 emit_move_insn (reg, mem);
19752 emit_insn (generate_set_vrsave (reg, info, 1));
19755 /* Get the old lr if we saved it. If we are restoring registers
19756 out-of-line, then the out-of-line routines can do this for us. */
19757 if (restore_lr && restoring_GPRs_inline)
19759 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19760 info->lr_save_offset + sp_offset);
19762 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19765 /* Get the old cr if we saved it. */
19766 if (info->cr_save_p)
19768 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19769 GEN_INT (info->cr_save_offset + sp_offset));
19770 rtx mem = gen_frame_mem (SImode, addr);
19772 cr_save_reg = gen_rtx_REG (SImode,
19773 DEFAULT_ABI == ABI_AIX
19774 && !restoring_GPRs_inline
19775 && info->first_fp_reg_save < 64
19777 emit_move_insn (cr_save_reg, mem);
19780 /* Set LR here to try to overlap restores below. LR is always saved
19781 above incoming stack, so it never needs REG_CFA_RESTORE. */
19782 if (restore_lr && restoring_GPRs_inline)
19783 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19784 gen_rtx_REG (Pmode, 0));
19786 /* Load exception handler data registers, if needed. */
19787 if (crtl->calls_eh_return)
19789 unsigned int i, regno;
19793 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19794 GEN_INT (sp_offset + 5 * reg_size));
19795 rtx mem = gen_frame_mem (reg_mode, addr);
19797 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19804 regno = EH_RETURN_DATA_REGNO (i);
19805 if (regno == INVALID_REGNUM)
19808 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19809 info->ehrd_offset + sp_offset
19810 + reg_size * (int) i);
19812 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19816 /* Restore GPRs. This is done as a PARALLEL if we are using
19817 the load-multiple instructions. */
19819 && info->spe_64bit_regs_used != 0
19820 && info->first_gp_reg_save != 32)
19822 /* Determine whether we can address all of the registers that need
19823 to be saved with an offset from the stack pointer that fits in
19824 the small const field for SPE memory instructions. */
19825 int spe_regs_addressable_via_sp
19826 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19827 + (32 - info->first_gp_reg_save - 1) * reg_size)
19828 && restoring_GPRs_inline);
19831 if (spe_regs_addressable_via_sp)
19832 spe_offset = info->spe_gp_save_offset + sp_offset;
19835 rtx old_frame_reg_rtx = frame_reg_rtx;
19836 /* Make r11 point to the start of the SPE save area. We worried about
19837 not clobbering it when we were saving registers in the prologue.
19838 There's no need to worry here because the static chain is passed
19839 anew to every function. */
19840 int ool_adjust = (restoring_GPRs_inline
19842 : (info->first_gp_reg_save
19843 - (FIRST_SAVRES_REGISTER+1))*8);
19845 if (frame_reg_rtx == sp_reg_rtx)
19846 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19847 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19848 GEN_INT (info->spe_gp_save_offset
19851 /* Keep the invariant that frame_reg_rtx + sp_offset points
19852 at the top of the stack frame. */
19853 sp_offset = -info->spe_gp_save_offset;
19858 if (restoring_GPRs_inline)
19860 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19861 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19863 rtx offset, addr, mem, reg;
19865 /* We're doing all this to ensure that the immediate offset
19866 fits into the immediate field of 'evldd'. */
19867 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19869 offset = GEN_INT (spe_offset + reg_size * i);
19870 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19871 mem = gen_rtx_MEM (V2SImode, addr);
19872 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19874 insn = emit_move_insn (reg, mem);
19875 if (DEFAULT_ABI == ABI_V4)
19877 if (frame_pointer_needed
19878 && info->first_gp_reg_save + i
19879 == HARD_FRAME_POINTER_REGNUM)
19881 add_reg_note (insn, REG_CFA_DEF_CFA,
19882 plus_constant (frame_reg_rtx,
19884 RTX_FRAME_RELATED_P (insn) = 1;
19887 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19896 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19898 /*savep=*/false, /*gpr=*/true,
19900 emit_jump_insn (par);
19901 /* We don't want anybody else emitting things after we jumped
19906 else if (!restoring_GPRs_inline)
19908 /* We are jumping to an out-of-line function. */
19909 bool can_use_exit = info->first_fp_reg_save == 64;
19912 /* Emit stack reset code if we need it. */
19914 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19915 sp_offset, can_use_exit);
19918 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19921 GEN_INT (sp_offset - info->fp_size)));
19922 if (REGNO (frame_reg_rtx) == 11)
19923 sp_offset += info->fp_size;
19926 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19927 info->gp_save_offset, reg_mode,
19928 /*savep=*/false, /*gpr=*/true,
19929 /*lr=*/can_use_exit);
19933 if (info->cr_save_p)
19935 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19936 if (DEFAULT_ABI == ABI_V4)
19938 = alloc_reg_note (REG_CFA_RESTORE,
19939 gen_rtx_REG (SImode, CR2_REGNO),
19943 emit_jump_insn (par);
19945 /* We don't want anybody else emitting things after we jumped
19950 insn = emit_insn (par);
19951 if (DEFAULT_ABI == ABI_V4)
19953 if (frame_pointer_needed)
19955 add_reg_note (insn, REG_CFA_DEF_CFA,
19956 plus_constant (frame_reg_rtx, sp_offset));
19957 RTX_FRAME_RELATED_P (insn) = 1;
19960 for (i = info->first_gp_reg_save; i < 32; i++)
19962 = alloc_reg_note (REG_CFA_RESTORE,
19963 gen_rtx_REG (reg_mode, i), cfa_restores);
19966 else if (using_load_multiple)
19969 p = rtvec_alloc (32 - info->first_gp_reg_save);
19970 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19972 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19973 GEN_INT (info->gp_save_offset
19976 rtx mem = gen_frame_mem (reg_mode, addr);
19977 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19979 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19980 if (DEFAULT_ABI == ABI_V4)
19981 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19984 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19985 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19987 add_reg_note (insn, REG_CFA_DEF_CFA,
19988 plus_constant (frame_reg_rtx, sp_offset));
19989 RTX_FRAME_RELATED_P (insn) = 1;
19994 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19995 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19997 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19998 GEN_INT (info->gp_save_offset
20001 rtx mem = gen_frame_mem (reg_mode, addr);
20002 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20004 insn = emit_move_insn (reg, mem);
20005 if (DEFAULT_ABI == ABI_V4)
20007 if (frame_pointer_needed
20008 && info->first_gp_reg_save + i
20009 == HARD_FRAME_POINTER_REGNUM)
20011 add_reg_note (insn, REG_CFA_DEF_CFA,
20012 plus_constant (frame_reg_rtx, sp_offset));
20013 RTX_FRAME_RELATED_P (insn) = 1;
20016 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20022 if (restore_lr && !restoring_GPRs_inline)
20024 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20025 info->lr_save_offset + sp_offset);
20027 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20028 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20029 gen_rtx_REG (Pmode, 0));
20032 /* Restore fpr's if we need to do it without calling a function. */
20033 if (restoring_FPRs_inline)
20034 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20035 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20036 && ! call_used_regs[info->first_fp_reg_save+i]))
20038 rtx addr, mem, reg;
20039 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20040 GEN_INT (info->fp_save_offset
20043 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20044 ? DFmode : SFmode), addr);
20045 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20046 ? DFmode : SFmode),
20047 info->first_fp_reg_save + i);
20049 emit_move_insn (reg, mem);
20050 if (DEFAULT_ABI == ABI_V4)
20051 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20055 /* If we saved cr, restore it here. Just those that were used. */
20056 if (info->cr_save_p)
20058 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20059 if (DEFAULT_ABI == ABI_V4)
20061 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20065 /* If this is V.4, unwind the stack pointer after all of the loads
20067 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20068 sp_offset, !restoring_FPRs_inline);
20073 REG_NOTES (insn) = cfa_restores;
20074 cfa_restores = NULL_RTX;
20076 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20077 RTX_FRAME_RELATED_P (insn) = 1;
20080 if (crtl->calls_eh_return)
20082 rtx sa = EH_RETURN_STACKADJ_RTX;
20083 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20089 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20090 if (! restoring_FPRs_inline)
20091 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20093 p = rtvec_alloc (2);
20095 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20096 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20097 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20098 : gen_rtx_CLOBBER (VOIDmode,
20099 gen_rtx_REG (Pmode, 65)));
20101 /* If we have to restore more than two FP registers, branch to the
20102 restore function. It will return to our caller. */
20103 if (! restoring_FPRs_inline)
20108 sym = rs6000_savres_routine_sym (info,
20112 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20113 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20114 gen_rtx_REG (Pmode,
20115 DEFAULT_ABI == ABI_AIX
20117 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20120 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20121 GEN_INT (info->fp_save_offset + 8*i));
20122 mem = gen_frame_mem (DFmode, addr);
20124 RTVEC_ELT (p, i+4) =
20125 gen_rtx_SET (VOIDmode,
20126 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20131 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20135 /* Write function epilogue. */
20138 rs6000_output_function_epilogue (FILE *file,
20139 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20141 if (! HAVE_epilogue)
20143 rtx insn = get_last_insn ();
20144 /* If the last insn was a BARRIER, we don't have to write anything except
20145 the trace table. */
20146 if (GET_CODE (insn) == NOTE)
20147 insn = prev_nonnote_insn (insn);
20148 if (insn == 0 || GET_CODE (insn) != BARRIER)
20150 /* This is slightly ugly, but at least we don't have two
20151 copies of the epilogue-emitting code. */
20154 /* A NOTE_INSN_DELETED is supposed to be at the start
20155 and end of the "toplevel" insn chain. */
20156 emit_note (NOTE_INSN_DELETED);
20157 rs6000_emit_epilogue (FALSE);
20158 emit_note (NOTE_INSN_DELETED);
20160 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20164 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20166 INSN_ADDRESSES_NEW (insn, addr);
20171 if (TARGET_DEBUG_STACK)
20172 debug_rtx_list (get_insns (), 100);
20173 final (get_insns (), file, FALSE);
20179 macho_branch_islands ();
20180 /* Mach-O doesn't support labels at the end of objects, so if
20181 it looks like we might want one, insert a NOP. */
20183 rtx insn = get_last_insn ();
20186 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20187 insn = PREV_INSN (insn);
20191 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20192 fputs ("\tnop\n", file);
20196 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20199 We don't output a traceback table if -finhibit-size-directive was
20200 used. The documentation for -finhibit-size-directive reads
20201 ``don't output a @code{.size} assembler directive, or anything
20202 else that would cause trouble if the function is split in the
20203 middle, and the two halves are placed at locations far apart in
20204 memory.'' The traceback table has this property, since it
20205 includes the offset from the start of the function to the
20206 traceback table itself.
20208 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20209 different traceback table. */
20210 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20211 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20213 const char *fname = NULL;
20214 const char *language_string = lang_hooks.name;
20215 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20217 int optional_tbtab;
20218 rs6000_stack_t *info = rs6000_stack_info ();
20220 if (rs6000_traceback == traceback_full)
20221 optional_tbtab = 1;
20222 else if (rs6000_traceback == traceback_part)
20223 optional_tbtab = 0;
20225 optional_tbtab = !optimize_size && !TARGET_ELF;
20227 if (optional_tbtab)
20229 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20230 while (*fname == '.') /* V.4 encodes . in the name */
20233 /* Need label immediately before tbtab, so we can compute
20234 its offset from the function start. */
20235 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20236 ASM_OUTPUT_LABEL (file, fname);
20239 /* The .tbtab pseudo-op can only be used for the first eight
20240 expressions, since it can't handle the possibly variable
20241 length fields that follow. However, if you omit the optional
20242 fields, the assembler outputs zeros for all optional fields
20243 anyways, giving each variable length field is minimum length
20244 (as defined in sys/debug.h). Thus we can not use the .tbtab
20245 pseudo-op at all. */
20247 /* An all-zero word flags the start of the tbtab, for debuggers
20248 that have to find it by searching forward from the entry
20249 point or from the current pc. */
20250 fputs ("\t.long 0\n", file);
20252 /* Tbtab format type. Use format type 0. */
20253 fputs ("\t.byte 0,", file);
20255 /* Language type. Unfortunately, there does not seem to be any
20256 official way to discover the language being compiled, so we
20257 use language_string.
20258 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20259 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20260 a number, so for now use 9. LTO isn't assigned a number either,
20261 so for now use 0. */
20262 if (! strcmp (language_string, "GNU C")
20263 || ! strcmp (language_string, "GNU GIMPLE"))
20265 else if (! strcmp (language_string, "GNU F77")
20266 || ! strcmp (language_string, "GNU Fortran"))
20268 else if (! strcmp (language_string, "GNU Pascal"))
20270 else if (! strcmp (language_string, "GNU Ada"))
20272 else if (! strcmp (language_string, "GNU C++")
20273 || ! strcmp (language_string, "GNU Objective-C++"))
20275 else if (! strcmp (language_string, "GNU Java"))
20277 else if (! strcmp (language_string, "GNU Objective-C"))
20280 gcc_unreachable ();
20281 fprintf (file, "%d,", i);
20283 /* 8 single bit fields: global linkage (not set for C extern linkage,
20284 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20285 from start of procedure stored in tbtab, internal function, function
20286 has controlled storage, function has no toc, function uses fp,
20287 function logs/aborts fp operations. */
20288 /* Assume that fp operations are used if any fp reg must be saved. */
20289 fprintf (file, "%d,",
20290 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20292 /* 6 bitfields: function is interrupt handler, name present in
20293 proc table, function calls alloca, on condition directives
20294 (controls stack walks, 3 bits), saves condition reg, saves
20296 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20297 set up as a frame pointer, even when there is no alloca call. */
20298 fprintf (file, "%d,",
20299 ((optional_tbtab << 6)
20300 | ((optional_tbtab & frame_pointer_needed) << 5)
20301 | (info->cr_save_p << 1)
20302 | (info->lr_save_p)));
20304 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20306 fprintf (file, "%d,",
20307 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20309 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20310 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20312 if (optional_tbtab)
20314 /* Compute the parameter info from the function decl argument
20317 int next_parm_info_bit = 31;
20319 for (decl = DECL_ARGUMENTS (current_function_decl);
20320 decl; decl = TREE_CHAIN (decl))
20322 rtx parameter = DECL_INCOMING_RTL (decl);
20323 enum machine_mode mode = GET_MODE (parameter);
20325 if (GET_CODE (parameter) == REG)
20327 if (SCALAR_FLOAT_MODE_P (mode))
20348 gcc_unreachable ();
20351 /* If only one bit will fit, don't or in this entry. */
20352 if (next_parm_info_bit > 0)
20353 parm_info |= (bits << (next_parm_info_bit - 1));
20354 next_parm_info_bit -= 2;
20358 fixed_parms += ((GET_MODE_SIZE (mode)
20359 + (UNITS_PER_WORD - 1))
20361 next_parm_info_bit -= 1;
20367 /* Number of fixed point parameters. */
20368 /* This is actually the number of words of fixed point parameters; thus
20369 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20370 fprintf (file, "%d,", fixed_parms);
20372 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20374 /* This is actually the number of fp registers that hold parameters;
20375 and thus the maximum value is 13. */
20376 /* Set parameters on stack bit if parameters are not in their original
20377 registers, regardless of whether they are on the stack? Xlc
20378 seems to set the bit when not optimizing. */
20379 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20381 if (! optional_tbtab)
20384 /* Optional fields follow. Some are variable length. */
20386 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20387 11 double float. */
20388 /* There is an entry for each parameter in a register, in the order that
20389 they occur in the parameter list. Any intervening arguments on the
20390 stack are ignored. If the list overflows a long (max possible length
20391 34 bits) then completely leave off all elements that don't fit. */
20392 /* Only emit this long if there was at least one parameter. */
20393 if (fixed_parms || float_parms)
20394 fprintf (file, "\t.long %d\n", parm_info);
20396 /* Offset from start of code to tb table. */
20397 fputs ("\t.long ", file);
20398 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20400 RS6000_OUTPUT_BASENAME (file, fname);
20402 assemble_name (file, fname);
20404 rs6000_output_function_entry (file, fname);
20407 /* Interrupt handler mask. */
20408 /* Omit this long, since we never set the interrupt handler bit
20411 /* Number of CTL (controlled storage) anchors. */
20412 /* Omit this long, since the has_ctl bit is never set above. */
20414 /* Displacement into stack of each CTL anchor. */
20415 /* Omit this list of longs, because there are no CTL anchors. */
20417 /* Length of function name. */
20420 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20422 /* Function name. */
20423 assemble_string (fname, strlen (fname));
20425 /* Register for alloca automatic storage; this is always reg 31.
20426 Only emit this if the alloca bit was set above. */
20427 if (frame_pointer_needed)
20428 fputs ("\t.byte 31\n", file);
20430 fputs ("\t.align 2\n", file);
20434 /* A C compound statement that outputs the assembler code for a thunk
20435 function, used to implement C++ virtual function calls with
20436 multiple inheritance. The thunk acts as a wrapper around a virtual
20437 function, adjusting the implicit object parameter before handing
20438 control off to the real function.
20440 First, emit code to add the integer DELTA to the location that
20441 contains the incoming first argument. Assume that this argument
20442 contains a pointer, and is the one used to pass the `this' pointer
20443 in C++. This is the incoming argument *before* the function
20444 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20445 values of all other incoming arguments.
20447 After the addition, emit code to jump to FUNCTION, which is a
20448 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20449 not touch the return address. Hence returning from FUNCTION will
20450 return to whoever called the current `thunk'.
20452 The effect must be as if FUNCTION had been called directly with the
20453 adjusted first argument. This macro is responsible for emitting
20454 all of the code for a thunk function; output_function_prologue()
20455 and output_function_epilogue() are not invoked.
20457 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20458 been extracted from it.) It might possibly be useful on some
20459 targets, but probably not.
20461 If you do not define this macro, the target-independent code in the
20462 C++ frontend will generate a less efficient heavyweight thunk that
20463 calls FUNCTION instead of jumping to it. The generic approach does
20464 not support varargs. */
20467 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20468 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20471 rtx this_rtx, insn, funexp;
20473 reload_completed = 1;
20474 epilogue_completed = 1;
20476 /* Mark the end of the (empty) prologue. */
20477 emit_note (NOTE_INSN_PROLOGUE_END);
20479 /* Find the "this" pointer. If the function returns a structure,
20480 the structure return pointer is in r3. */
20481 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20482 this_rtx = gen_rtx_REG (Pmode, 4);
20484 this_rtx = gen_rtx_REG (Pmode, 3);
20486 /* Apply the constant offset, if required. */
20488 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20490 /* Apply the offset from the vtable, if required. */
20493 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20494 rtx tmp = gen_rtx_REG (Pmode, 12);
20496 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20497 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20499 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20500 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20504 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20506 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20508 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20511 /* Generate a tail call to the target function. */
20512 if (!TREE_USED (function))
20514 assemble_external (function);
20515 TREE_USED (function) = 1;
20517 funexp = XEXP (DECL_RTL (function), 0);
20518 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20521 if (MACHOPIC_INDIRECT)
20522 funexp = machopic_indirect_call_target (funexp);
20525 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20526 generate sibcall RTL explicitly. */
20527 insn = emit_call_insn (
20528 gen_rtx_PARALLEL (VOIDmode,
20530 gen_rtx_CALL (VOIDmode,
20531 funexp, const0_rtx),
20532 gen_rtx_USE (VOIDmode, const0_rtx),
20533 gen_rtx_USE (VOIDmode,
20534 gen_rtx_REG (SImode,
20536 gen_rtx_RETURN (VOIDmode))));
20537 SIBLING_CALL_P (insn) = 1;
20540 /* Run just enough of rest_of_compilation to get the insns emitted.
20541 There's not really enough bulk here to make other passes such as
20542 instruction scheduling worth while. Note that use_thunk calls
20543 assemble_start_function and assemble_end_function. */
20544 insn = get_insns ();
20545 insn_locators_alloc ();
20546 shorten_branches (insn);
20547 final_start_function (insn, file, 1);
20548 final (insn, file, 1);
20549 final_end_function ();
20551 reload_completed = 0;
20552 epilogue_completed = 0;
20555 /* A quick summary of the various types of 'constant-pool tables'
20558 Target Flags Name One table per
20559 AIX (none) AIX TOC object file
20560 AIX -mfull-toc AIX TOC object file
20561 AIX -mminimal-toc AIX minimal TOC translation unit
20562 SVR4/EABI (none) SVR4 SDATA object file
20563 SVR4/EABI -fpic SVR4 pic object file
20564 SVR4/EABI -fPIC SVR4 PIC translation unit
20565 SVR4/EABI -mrelocatable EABI TOC function
20566 SVR4/EABI -maix AIX TOC object file
20567 SVR4/EABI -maix -mminimal-toc
20568 AIX minimal TOC translation unit
20570 Name Reg. Set by entries contains:
20571 made by addrs? fp? sum?
20573 AIX TOC 2 crt0 as Y option option
20574 AIX minimal TOC 30 prolog gcc Y Y option
20575 SVR4 SDATA 13 crt0 gcc N Y N
20576 SVR4 pic 30 prolog ld Y not yet N
20577 SVR4 PIC 30 prolog gcc Y option option
20578 EABI TOC 30 prolog gcc Y option option
20582 /* Hash functions for the hash table. */
20585 rs6000_hash_constant (rtx k)
20587 enum rtx_code code = GET_CODE (k);
20588 enum machine_mode mode = GET_MODE (k);
20589 unsigned result = (code << 3) ^ mode;
20590 const char *format;
20593 format = GET_RTX_FORMAT (code);
20594 flen = strlen (format);
20600 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20603 if (mode != VOIDmode)
20604 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20616 for (; fidx < flen; fidx++)
20617 switch (format[fidx])
20622 const char *str = XSTR (k, fidx);
20623 len = strlen (str);
20624 result = result * 613 + len;
20625 for (i = 0; i < len; i++)
20626 result = result * 613 + (unsigned) str[i];
20631 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20635 result = result * 613 + (unsigned) XINT (k, fidx);
20638 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20639 result = result * 613 + (unsigned) XWINT (k, fidx);
20643 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20644 result = result * 613 + (unsigned) (XWINT (k, fidx)
20651 gcc_unreachable ();
20658 toc_hash_function (const void *hash_entry)
20660 const struct toc_hash_struct *thc =
20661 (const struct toc_hash_struct *) hash_entry;
20662 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20665 /* Compare H1 and H2 for equivalence. */
20668 toc_hash_eq (const void *h1, const void *h2)
20670 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20671 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20673 if (((const struct toc_hash_struct *) h1)->key_mode
20674 != ((const struct toc_hash_struct *) h2)->key_mode)
20677 return rtx_equal_p (r1, r2);
20680 /* These are the names given by the C++ front-end to vtables, and
20681 vtable-like objects. Ideally, this logic should not be here;
20682 instead, there should be some programmatic way of inquiring as
20683 to whether or not an object is a vtable. */
20685 #define VTABLE_NAME_P(NAME) \
20686 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20687 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20688 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20689 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20690 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20692 #ifdef NO_DOLLAR_IN_LABEL
20693 /* Return a GGC-allocated character string translating dollar signs in
20694 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20697 rs6000_xcoff_strip_dollar (const char *name)
20702 p = strchr (name, '$');
20704 if (p == 0 || p == name)
20707 len = strlen (name);
20708 strip = (char *) alloca (len + 1);
20709 strcpy (strip, name);
20710 p = strchr (strip, '$');
20714 p = strchr (p + 1, '$');
20717 return ggc_alloc_string (strip, len);
20722 rs6000_output_symbol_ref (FILE *file, rtx x)
20724 /* Currently C++ toc references to vtables can be emitted before it
20725 is decided whether the vtable is public or private. If this is
20726 the case, then the linker will eventually complain that there is
20727 a reference to an unknown section. Thus, for vtables only,
20728 we emit the TOC reference to reference the symbol and not the
20730 const char *name = XSTR (x, 0);
20732 if (VTABLE_NAME_P (name))
20734 RS6000_OUTPUT_BASENAME (file, name);
20737 assemble_name (file, name);
20740 /* Output a TOC entry. We derive the entry name from what is being
20744 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20747 const char *name = buf;
20749 HOST_WIDE_INT offset = 0;
20751 gcc_assert (!TARGET_NO_TOC);
20753 /* When the linker won't eliminate them, don't output duplicate
20754 TOC entries (this happens on AIX if there is any kind of TOC,
20755 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20757 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20759 struct toc_hash_struct *h;
20762 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20763 time because GGC is not initialized at that point. */
20764 if (toc_hash_table == NULL)
20765 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20766 toc_hash_eq, NULL);
20768 h = GGC_NEW (struct toc_hash_struct);
20770 h->key_mode = mode;
20771 h->labelno = labelno;
20773 found = htab_find_slot (toc_hash_table, h, INSERT);
20774 if (*found == NULL)
20776 else /* This is indeed a duplicate.
20777 Set this label equal to that label. */
20779 fputs ("\t.set ", file);
20780 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20781 fprintf (file, "%d,", labelno);
20782 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20783 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20789 /* If we're going to put a double constant in the TOC, make sure it's
20790 aligned properly when strict alignment is on. */
20791 if (GET_CODE (x) == CONST_DOUBLE
20792 && STRICT_ALIGNMENT
20793 && GET_MODE_BITSIZE (mode) >= 64
20794 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20795 ASM_OUTPUT_ALIGN (file, 3);
20798 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20800 /* Handle FP constants specially. Note that if we have a minimal
20801 TOC, things we put here aren't actually in the TOC, so we can allow
20803 if (GET_CODE (x) == CONST_DOUBLE &&
20804 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20806 REAL_VALUE_TYPE rv;
20809 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20810 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20811 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20813 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20817 if (TARGET_MINIMAL_TOC)
20818 fputs (DOUBLE_INT_ASM_OP, file);
20820 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20821 k[0] & 0xffffffff, k[1] & 0xffffffff,
20822 k[2] & 0xffffffff, k[3] & 0xffffffff);
20823 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20824 k[0] & 0xffffffff, k[1] & 0xffffffff,
20825 k[2] & 0xffffffff, k[3] & 0xffffffff);
20830 if (TARGET_MINIMAL_TOC)
20831 fputs ("\t.long ", file);
20833 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20834 k[0] & 0xffffffff, k[1] & 0xffffffff,
20835 k[2] & 0xffffffff, k[3] & 0xffffffff);
20836 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20837 k[0] & 0xffffffff, k[1] & 0xffffffff,
20838 k[2] & 0xffffffff, k[3] & 0xffffffff);
20842 else if (GET_CODE (x) == CONST_DOUBLE &&
20843 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20845 REAL_VALUE_TYPE rv;
20848 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20850 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20851 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20853 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20857 if (TARGET_MINIMAL_TOC)
20858 fputs (DOUBLE_INT_ASM_OP, file);
20860 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20861 k[0] & 0xffffffff, k[1] & 0xffffffff);
20862 fprintf (file, "0x%lx%08lx\n",
20863 k[0] & 0xffffffff, k[1] & 0xffffffff);
20868 if (TARGET_MINIMAL_TOC)
20869 fputs ("\t.long ", file);
20871 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20872 k[0] & 0xffffffff, k[1] & 0xffffffff);
20873 fprintf (file, "0x%lx,0x%lx\n",
20874 k[0] & 0xffffffff, k[1] & 0xffffffff);
20878 else if (GET_CODE (x) == CONST_DOUBLE &&
20879 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20881 REAL_VALUE_TYPE rv;
20884 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20885 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20886 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20888 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20892 if (TARGET_MINIMAL_TOC)
20893 fputs (DOUBLE_INT_ASM_OP, file);
20895 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20896 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20901 if (TARGET_MINIMAL_TOC)
20902 fputs ("\t.long ", file);
20904 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20905 fprintf (file, "0x%lx\n", l & 0xffffffff);
20909 else if (GET_MODE (x) == VOIDmode
20910 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20912 unsigned HOST_WIDE_INT low;
20913 HOST_WIDE_INT high;
20915 if (GET_CODE (x) == CONST_DOUBLE)
20917 low = CONST_DOUBLE_LOW (x);
20918 high = CONST_DOUBLE_HIGH (x);
20921 #if HOST_BITS_PER_WIDE_INT == 32
20924 high = (low & 0x80000000) ? ~0 : 0;
20928 low = INTVAL (x) & 0xffffffff;
20929 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20933 /* TOC entries are always Pmode-sized, but since this
20934 is a bigendian machine then if we're putting smaller
20935 integer constants in the TOC we have to pad them.
20936 (This is still a win over putting the constants in
20937 a separate constant pool, because then we'd have
20938 to have both a TOC entry _and_ the actual constant.)
20940 For a 32-bit target, CONST_INT values are loaded and shifted
20941 entirely within `low' and can be stored in one TOC entry. */
20943 /* It would be easy to make this work, but it doesn't now. */
20944 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20946 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20948 #if HOST_BITS_PER_WIDE_INT == 32
20949 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20950 POINTER_SIZE, &low, &high, 0);
20953 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20954 high = (HOST_WIDE_INT) low >> 32;
20961 if (TARGET_MINIMAL_TOC)
20962 fputs (DOUBLE_INT_ASM_OP, file);
20964 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20965 (long) high & 0xffffffff, (long) low & 0xffffffff);
20966 fprintf (file, "0x%lx%08lx\n",
20967 (long) high & 0xffffffff, (long) low & 0xffffffff);
20972 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20974 if (TARGET_MINIMAL_TOC)
20975 fputs ("\t.long ", file);
20977 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20978 (long) high & 0xffffffff, (long) low & 0xffffffff);
20979 fprintf (file, "0x%lx,0x%lx\n",
20980 (long) high & 0xffffffff, (long) low & 0xffffffff);
20984 if (TARGET_MINIMAL_TOC)
20985 fputs ("\t.long ", file);
20987 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20988 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20994 if (GET_CODE (x) == CONST)
20996 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20997 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20999 base = XEXP (XEXP (x, 0), 0);
21000 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21003 switch (GET_CODE (base))
21006 name = XSTR (base, 0);
21010 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21011 CODE_LABEL_NUMBER (XEXP (base, 0)));
21015 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21019 gcc_unreachable ();
21022 if (TARGET_MINIMAL_TOC)
21023 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21026 fputs ("\t.tc ", file);
21027 RS6000_OUTPUT_BASENAME (file, name);
21030 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21032 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21034 fputs ("[TC],", file);
21037 /* Currently C++ toc references to vtables can be emitted before it
21038 is decided whether the vtable is public or private. If this is
21039 the case, then the linker will eventually complain that there is
21040 a TOC reference to an unknown section. Thus, for vtables only,
21041 we emit the TOC reference to reference the symbol and not the
21043 if (VTABLE_NAME_P (name))
21045 RS6000_OUTPUT_BASENAME (file, name);
21047 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21048 else if (offset > 0)
21049 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21052 output_addr_const (file, x);
21056 /* Output an assembler pseudo-op to write an ASCII string of N characters
21057 starting at P to FILE.
21059 On the RS/6000, we have to do this using the .byte operation and
21060 write out special characters outside the quoted string.
21061 Also, the assembler is broken; very long strings are truncated,
21062 so we must artificially break them up early. */
21065 output_ascii (FILE *file, const char *p, int n)
21068 int i, count_string;
21069 const char *for_string = "\t.byte \"";
21070 const char *for_decimal = "\t.byte ";
21071 const char *to_close = NULL;
21074 for (i = 0; i < n; i++)
21077 if (c >= ' ' && c < 0177)
21080 fputs (for_string, file);
21083 /* Write two quotes to get one. */
21091 for_decimal = "\"\n\t.byte ";
21095 if (count_string >= 512)
21097 fputs (to_close, file);
21099 for_string = "\t.byte \"";
21100 for_decimal = "\t.byte ";
21108 fputs (for_decimal, file);
21109 fprintf (file, "%d", c);
21111 for_string = "\n\t.byte \"";
21112 for_decimal = ", ";
21118 /* Now close the string if we have written one. Then end the line. */
21120 fputs (to_close, file);
21123 /* Generate a unique section name for FILENAME for a section type
21124 represented by SECTION_DESC. Output goes into BUF.
21126 SECTION_DESC can be any string, as long as it is different for each
21127 possible section type.
21129 We name the section in the same manner as xlc. The name begins with an
21130 underscore followed by the filename (after stripping any leading directory
21131 names) with the last period replaced by the string SECTION_DESC. If
21132 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21136 rs6000_gen_section_name (char **buf, const char *filename,
21137 const char *section_desc)
21139 const char *q, *after_last_slash, *last_period = 0;
21143 after_last_slash = filename;
21144 for (q = filename; *q; q++)
21147 after_last_slash = q + 1;
21148 else if (*q == '.')
21152 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21153 *buf = (char *) xmalloc (len);
21158 for (q = after_last_slash; *q; q++)
21160 if (q == last_period)
21162 strcpy (p, section_desc);
21163 p += strlen (section_desc);
21167 else if (ISALNUM (*q))
21171 if (last_period == 0)
21172 strcpy (p, section_desc);
21177 /* Emit profile function. */
21180 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21182 /* Non-standard profiling for kernels, which just saves LR then calls
21183 _mcount without worrying about arg saves. The idea is to change
21184 the function prologue as little as possible as it isn't easy to
21185 account for arg save/restore code added just for _mcount. */
21186 if (TARGET_PROFILE_KERNEL)
21189 if (DEFAULT_ABI == ABI_AIX)
21191 #ifndef NO_PROFILE_COUNTERS
21192 # define NO_PROFILE_COUNTERS 0
21194 if (NO_PROFILE_COUNTERS)
21195 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21196 LCT_NORMAL, VOIDmode, 0);
21200 const char *label_name;
21203 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21204 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21205 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21207 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21208 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21211 else if (DEFAULT_ABI == ABI_DARWIN)
21213 const char *mcount_name = RS6000_MCOUNT;
21214 int caller_addr_regno = LR_REGNO;
21216 /* Be conservative and always set this, at least for now. */
21217 crtl->uses_pic_offset_table = 1;
21220 /* For PIC code, set up a stub and collect the caller's address
21221 from r0, which is where the prologue puts it. */
21222 if (MACHOPIC_INDIRECT
21223 && crtl->uses_pic_offset_table)
21224 caller_addr_regno = 0;
21226 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21227 LCT_NORMAL, VOIDmode, 1,
21228 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21232 /* Write function profiler code. */
21235 output_function_profiler (FILE *file, int labelno)
21239 switch (DEFAULT_ABI)
21242 gcc_unreachable ();
21247 warning (0, "no profiling of 64-bit code for this ABI");
21250 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21251 fprintf (file, "\tmflr %s\n", reg_names[0]);
21252 if (NO_PROFILE_COUNTERS)
21254 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21255 reg_names[0], reg_names[1]);
21257 else if (TARGET_SECURE_PLT && flag_pic)
21259 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21260 reg_names[0], reg_names[1]);
21261 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21262 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21263 reg_names[12], reg_names[12]);
21264 assemble_name (file, buf);
21265 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21266 assemble_name (file, buf);
21267 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21269 else if (flag_pic == 1)
21271 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21272 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21273 reg_names[0], reg_names[1]);
21274 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21275 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21276 assemble_name (file, buf);
21277 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21279 else if (flag_pic > 1)
21281 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21282 reg_names[0], reg_names[1]);
21283 /* Now, we need to get the address of the label. */
21284 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21285 assemble_name (file, buf);
21286 fputs ("-.\n1:", file);
21287 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21288 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21289 reg_names[0], reg_names[11]);
21290 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21291 reg_names[0], reg_names[0], reg_names[11]);
21295 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21296 assemble_name (file, buf);
21297 fputs ("@ha\n", file);
21298 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21299 reg_names[0], reg_names[1]);
21300 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21301 assemble_name (file, buf);
21302 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21305 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21306 fprintf (file, "\tbl %s%s\n",
21307 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21312 if (!TARGET_PROFILE_KERNEL)
21314 /* Don't do anything, done in output_profile_hook (). */
21318 gcc_assert (!TARGET_32BIT);
21320 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21321 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21323 if (cfun->static_chain_decl != NULL)
21325 asm_fprintf (file, "\tstd %s,24(%s)\n",
21326 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21327 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21328 asm_fprintf (file, "\tld %s,24(%s)\n",
21329 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21332 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21340 /* The following variable value is the last issued insn. */
21342 static rtx last_scheduled_insn;
21344 /* The following variable helps to balance issuing of load and
21345 store instructions */
21347 static int load_store_pendulum;
21349 /* Power4 load update and store update instructions are cracked into a
21350 load or store and an integer insn which are executed in the same cycle.
21351 Branches have their own dispatch slot which does not count against the
21352 GCC issue rate, but it changes the program flow so there are no other
21353 instructions to issue in this cycle. */
21356 rs6000_variable_issue_1 (rtx insn, int more)
21358 last_scheduled_insn = insn;
21359 if (GET_CODE (PATTERN (insn)) == USE
21360 || GET_CODE (PATTERN (insn)) == CLOBBER)
21362 cached_can_issue_more = more;
21363 return cached_can_issue_more;
21366 if (insn_terminates_group_p (insn, current_group))
21368 cached_can_issue_more = 0;
21369 return cached_can_issue_more;
21372 /* If no reservation, but reach here */
21373 if (recog_memoized (insn) < 0)
21376 if (rs6000_sched_groups)
21378 if (is_microcoded_insn (insn))
21379 cached_can_issue_more = 0;
21380 else if (is_cracked_insn (insn))
21381 cached_can_issue_more = more > 2 ? more - 2 : 0;
21383 cached_can_issue_more = more - 1;
21385 return cached_can_issue_more;
21388 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21391 cached_can_issue_more = more - 1;
21392 return cached_can_issue_more;
21396 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21398 int r = rs6000_variable_issue_1 (insn, more);
21400 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21404 /* Adjust the cost of a scheduling dependency. Return the new cost of
21405 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21408 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21410 enum attr_type attr_type;
21412 if (! recog_memoized (insn))
21415 switch (REG_NOTE_KIND (link))
21419 /* Data dependency; DEP_INSN writes a register that INSN reads
21420 some cycles later. */
21422 /* Separate a load from a narrower, dependent store. */
21423 if (rs6000_sched_groups
21424 && GET_CODE (PATTERN (insn)) == SET
21425 && GET_CODE (PATTERN (dep_insn)) == SET
21426 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21427 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21428 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21429 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21432 attr_type = get_attr_type (insn);
21437 /* Tell the first scheduling pass about the latency between
21438 a mtctr and bctr (and mtlr and br/blr). The first
21439 scheduling pass will not know about this latency since
21440 the mtctr instruction, which has the latency associated
21441 to it, will be generated by reload. */
21442 return TARGET_POWER ? 5 : 4;
21444 /* Leave some extra cycles between a compare and its
21445 dependent branch, to inhibit expensive mispredicts. */
21446 if ((rs6000_cpu_attr == CPU_PPC603
21447 || rs6000_cpu_attr == CPU_PPC604
21448 || rs6000_cpu_attr == CPU_PPC604E
21449 || rs6000_cpu_attr == CPU_PPC620
21450 || rs6000_cpu_attr == CPU_PPC630
21451 || rs6000_cpu_attr == CPU_PPC750
21452 || rs6000_cpu_attr == CPU_PPC7400
21453 || rs6000_cpu_attr == CPU_PPC7450
21454 || rs6000_cpu_attr == CPU_POWER4
21455 || rs6000_cpu_attr == CPU_POWER5
21456 || rs6000_cpu_attr == CPU_POWER7
21457 || rs6000_cpu_attr == CPU_CELL)
21458 && recog_memoized (dep_insn)
21459 && (INSN_CODE (dep_insn) >= 0))
21461 switch (get_attr_type (dep_insn))
21465 case TYPE_DELAYED_COMPARE:
21466 case TYPE_IMUL_COMPARE:
21467 case TYPE_LMUL_COMPARE:
21468 case TYPE_FPCOMPARE:
21469 case TYPE_CR_LOGICAL:
21470 case TYPE_DELAYED_CR:
21479 case TYPE_STORE_UX:
21481 case TYPE_FPSTORE_U:
21482 case TYPE_FPSTORE_UX:
21483 if ((rs6000_cpu == PROCESSOR_POWER6)
21484 && recog_memoized (dep_insn)
21485 && (INSN_CODE (dep_insn) >= 0))
21488 if (GET_CODE (PATTERN (insn)) != SET)
21489 /* If this happens, we have to extend this to schedule
21490 optimally. Return default for now. */
21493 /* Adjust the cost for the case where the value written
21494 by a fixed point operation is used as the address
21495 gen value on a store. */
21496 switch (get_attr_type (dep_insn))
21503 if (! store_data_bypass_p (dep_insn, insn))
21507 case TYPE_LOAD_EXT:
21508 case TYPE_LOAD_EXT_U:
21509 case TYPE_LOAD_EXT_UX:
21510 case TYPE_VAR_SHIFT_ROTATE:
21511 case TYPE_VAR_DELAYED_COMPARE:
21513 if (! store_data_bypass_p (dep_insn, insn))
21519 case TYPE_FAST_COMPARE:
21522 case TYPE_INSERT_WORD:
21523 case TYPE_INSERT_DWORD:
21524 case TYPE_FPLOAD_U:
21525 case TYPE_FPLOAD_UX:
21527 case TYPE_STORE_UX:
21528 case TYPE_FPSTORE_U:
21529 case TYPE_FPSTORE_UX:
21531 if (! store_data_bypass_p (dep_insn, insn))
21539 case TYPE_IMUL_COMPARE:
21540 case TYPE_LMUL_COMPARE:
21542 if (! store_data_bypass_p (dep_insn, insn))
21548 if (! store_data_bypass_p (dep_insn, insn))
21554 if (! store_data_bypass_p (dep_insn, insn))
21567 case TYPE_LOAD_EXT:
21568 case TYPE_LOAD_EXT_U:
21569 case TYPE_LOAD_EXT_UX:
21570 if ((rs6000_cpu == PROCESSOR_POWER6)
21571 && recog_memoized (dep_insn)
21572 && (INSN_CODE (dep_insn) >= 0))
21575 /* Adjust the cost for the case where the value written
21576 by a fixed point instruction is used within the address
21577 gen portion of a subsequent load(u)(x) */
21578 switch (get_attr_type (dep_insn))
21585 if (set_to_load_agen (dep_insn, insn))
21589 case TYPE_LOAD_EXT:
21590 case TYPE_LOAD_EXT_U:
21591 case TYPE_LOAD_EXT_UX:
21592 case TYPE_VAR_SHIFT_ROTATE:
21593 case TYPE_VAR_DELAYED_COMPARE:
21595 if (set_to_load_agen (dep_insn, insn))
21601 case TYPE_FAST_COMPARE:
21604 case TYPE_INSERT_WORD:
21605 case TYPE_INSERT_DWORD:
21606 case TYPE_FPLOAD_U:
21607 case TYPE_FPLOAD_UX:
21609 case TYPE_STORE_UX:
21610 case TYPE_FPSTORE_U:
21611 case TYPE_FPSTORE_UX:
21613 if (set_to_load_agen (dep_insn, insn))
21621 case TYPE_IMUL_COMPARE:
21622 case TYPE_LMUL_COMPARE:
21624 if (set_to_load_agen (dep_insn, insn))
21630 if (set_to_load_agen (dep_insn, insn))
21636 if (set_to_load_agen (dep_insn, insn))
21647 if ((rs6000_cpu == PROCESSOR_POWER6)
21648 && recog_memoized (dep_insn)
21649 && (INSN_CODE (dep_insn) >= 0)
21650 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21657 /* Fall out to return default cost. */
21661 case REG_DEP_OUTPUT:
21662 /* Output dependency; DEP_INSN writes a register that INSN writes some
21664 if ((rs6000_cpu == PROCESSOR_POWER6)
21665 && recog_memoized (dep_insn)
21666 && (INSN_CODE (dep_insn) >= 0))
21668 attr_type = get_attr_type (insn);
21673 if (get_attr_type (dep_insn) == TYPE_FP)
21677 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21685 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21690 gcc_unreachable ();
21696 /* Debug version of rs6000_adjust_cost. */
21699 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21701 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21707 switch (REG_NOTE_KIND (link))
21709 default: dep = "unknown depencency"; break;
21710 case REG_DEP_TRUE: dep = "data dependency"; break;
21711 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21712 case REG_DEP_ANTI: dep = "anti depencency"; break;
21716 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21717 "%s, insn:\n", ret, cost, dep);
21725 /* The function returns a true if INSN is microcoded.
21726 Return false otherwise. */
21729 is_microcoded_insn (rtx insn)
21731 if (!insn || !NONDEBUG_INSN_P (insn)
21732 || GET_CODE (PATTERN (insn)) == USE
21733 || GET_CODE (PATTERN (insn)) == CLOBBER)
21736 if (rs6000_cpu_attr == CPU_CELL)
21737 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21739 if (rs6000_sched_groups)
21741 enum attr_type type = get_attr_type (insn);
21742 if (type == TYPE_LOAD_EXT_U
21743 || type == TYPE_LOAD_EXT_UX
21744 || type == TYPE_LOAD_UX
21745 || type == TYPE_STORE_UX
21746 || type == TYPE_MFCR)
21753 /* The function returns true if INSN is cracked into 2 instructions
21754 by the processor (and therefore occupies 2 issue slots). */
21757 is_cracked_insn (rtx insn)
21759 if (!insn || !NONDEBUG_INSN_P (insn)
21760 || GET_CODE (PATTERN (insn)) == USE
21761 || GET_CODE (PATTERN (insn)) == CLOBBER)
21764 if (rs6000_sched_groups)
21766 enum attr_type type = get_attr_type (insn);
21767 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21768 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21769 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21770 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21771 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21772 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21773 || type == TYPE_IDIV || type == TYPE_LDIV
21774 || type == TYPE_INSERT_WORD)
21781 /* The function returns true if INSN can be issued only from
21782 the branch slot. */
21785 is_branch_slot_insn (rtx insn)
21787 if (!insn || !NONDEBUG_INSN_P (insn)
21788 || GET_CODE (PATTERN (insn)) == USE
21789 || GET_CODE (PATTERN (insn)) == CLOBBER)
21792 if (rs6000_sched_groups)
21794 enum attr_type type = get_attr_type (insn);
21795 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21803 /* The function returns true if out_inst sets a value that is
21804 used in the address generation computation of in_insn */
21806 set_to_load_agen (rtx out_insn, rtx in_insn)
21808 rtx out_set, in_set;
21810 /* For performance reasons, only handle the simple case where
21811 both loads are a single_set. */
21812 out_set = single_set (out_insn);
21815 in_set = single_set (in_insn);
21817 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21823 /* The function returns true if the target storage location of
21824 out_insn is adjacent to the target storage location of in_insn */
21825 /* Return 1 if memory locations are adjacent. */
21828 adjacent_mem_locations (rtx insn1, rtx insn2)
21831 rtx a = get_store_dest (PATTERN (insn1));
21832 rtx b = get_store_dest (PATTERN (insn2));
21834 if ((GET_CODE (XEXP (a, 0)) == REG
21835 || (GET_CODE (XEXP (a, 0)) == PLUS
21836 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21837 && (GET_CODE (XEXP (b, 0)) == REG
21838 || (GET_CODE (XEXP (b, 0)) == PLUS
21839 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21841 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21844 if (GET_CODE (XEXP (a, 0)) == PLUS)
21846 reg0 = XEXP (XEXP (a, 0), 0);
21847 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21850 reg0 = XEXP (a, 0);
21852 if (GET_CODE (XEXP (b, 0)) == PLUS)
21854 reg1 = XEXP (XEXP (b, 0), 0);
21855 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21858 reg1 = XEXP (b, 0);
21860 val_diff = val1 - val0;
21862 return ((REGNO (reg0) == REGNO (reg1))
21863 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21864 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21870 /* A C statement (sans semicolon) to update the integer scheduling
21871 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21872 INSN earlier, reduce the priority to execute INSN later. Do not
21873 define this macro if you do not need to adjust the scheduling
21874 priorities of insns. */
21877 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21879 /* On machines (like the 750) which have asymmetric integer units,
21880 where one integer unit can do multiply and divides and the other
21881 can't, reduce the priority of multiply/divide so it is scheduled
21882 before other integer operations. */
21885 if (! INSN_P (insn))
21888 if (GET_CODE (PATTERN (insn)) == USE)
21891 switch (rs6000_cpu_attr) {
21893 switch (get_attr_type (insn))
21900 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21901 priority, priority);
21902 if (priority >= 0 && priority < 0x01000000)
21909 if (insn_must_be_first_in_group (insn)
21910 && reload_completed
21911 && current_sched_info->sched_max_insns_priority
21912 && rs6000_sched_restricted_insns_priority)
21915 /* Prioritize insns that can be dispatched only in the first
21917 if (rs6000_sched_restricted_insns_priority == 1)
21918 /* Attach highest priority to insn. This means that in
21919 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21920 precede 'priority' (critical path) considerations. */
21921 return current_sched_info->sched_max_insns_priority;
21922 else if (rs6000_sched_restricted_insns_priority == 2)
21923 /* Increase priority of insn by a minimal amount. This means that in
21924 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21925 considerations precede dispatch-slot restriction considerations. */
21926 return (priority + 1);
21929 if (rs6000_cpu == PROCESSOR_POWER6
21930 && ((load_store_pendulum == -2 && is_load_insn (insn))
21931 || (load_store_pendulum == 2 && is_store_insn (insn))))
21932 /* Attach highest priority to insn if the scheduler has just issued two
21933 stores and this instruction is a load, or two loads and this instruction
21934 is a store. Power6 wants loads and stores scheduled alternately
21936 return current_sched_info->sched_max_insns_priority;
21941 /* Return true if the instruction is nonpipelined on the Cell. */
21943 is_nonpipeline_insn (rtx insn)
21945 enum attr_type type;
21946 if (!insn || !NONDEBUG_INSN_P (insn)
21947 || GET_CODE (PATTERN (insn)) == USE
21948 || GET_CODE (PATTERN (insn)) == CLOBBER)
21951 type = get_attr_type (insn);
21952 if (type == TYPE_IMUL
21953 || type == TYPE_IMUL2
21954 || type == TYPE_IMUL3
21955 || type == TYPE_LMUL
21956 || type == TYPE_IDIV
21957 || type == TYPE_LDIV
21958 || type == TYPE_SDIV
21959 || type == TYPE_DDIV
21960 || type == TYPE_SSQRT
21961 || type == TYPE_DSQRT
21962 || type == TYPE_MFCR
21963 || type == TYPE_MFCRF
21964 || type == TYPE_MFJMPR)
21972 /* Return how many instructions the machine can issue per cycle. */
21975 rs6000_issue_rate (void)
21977 /* Unless scheduling for register pressure, use issue rate of 1 for
21978 first scheduling pass to decrease degradation. */
21979 if (!reload_completed && !flag_sched_pressure)
21982 switch (rs6000_cpu_attr) {
21983 case CPU_RIOS1: /* ? */
21985 case CPU_PPC601: /* ? */
21994 case CPU_PPCE300C2:
21995 case CPU_PPCE300C3:
21996 case CPU_PPCE500MC:
21997 case CPU_PPCE500MC64:
22016 /* Return how many instructions to look ahead for better insn
22020 rs6000_use_sched_lookahead (void)
22022 if (rs6000_cpu_attr == CPU_PPC8540)
22024 if (rs6000_cpu_attr == CPU_CELL)
22025 return (reload_completed ? 8 : 0);
22029 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22031 rs6000_use_sched_lookahead_guard (rtx insn)
22033 if (rs6000_cpu_attr != CPU_CELL)
22036 if (insn == NULL_RTX || !INSN_P (insn))
22039 if (!reload_completed
22040 || is_nonpipeline_insn (insn)
22041 || is_microcoded_insn (insn))
22047 /* Determine is PAT refers to memory. */
22050 is_mem_ref (rtx pat)
22056 /* stack_tie does not produce any real memory traffic. */
22057 if (GET_CODE (pat) == UNSPEC
22058 && XINT (pat, 1) == UNSPEC_TIE)
22061 if (GET_CODE (pat) == MEM)
22064 /* Recursively process the pattern. */
22065 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22067 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22070 ret |= is_mem_ref (XEXP (pat, i));
22071 else if (fmt[i] == 'E')
22072 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22073 ret |= is_mem_ref (XVECEXP (pat, i, j));
22079 /* Determine if PAT is a PATTERN of a load insn. */
22082 is_load_insn1 (rtx pat)
22084 if (!pat || pat == NULL_RTX)
22087 if (GET_CODE (pat) == SET)
22088 return is_mem_ref (SET_SRC (pat));
22090 if (GET_CODE (pat) == PARALLEL)
22094 for (i = 0; i < XVECLEN (pat, 0); i++)
22095 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22102 /* Determine if INSN loads from memory. */
22105 is_load_insn (rtx insn)
22107 if (!insn || !INSN_P (insn))
22110 if (GET_CODE (insn) == CALL_INSN)
22113 return is_load_insn1 (PATTERN (insn));
22116 /* Determine if PAT is a PATTERN of a store insn. */
22119 is_store_insn1 (rtx pat)
22121 if (!pat || pat == NULL_RTX)
22124 if (GET_CODE (pat) == SET)
22125 return is_mem_ref (SET_DEST (pat));
22127 if (GET_CODE (pat) == PARALLEL)
22131 for (i = 0; i < XVECLEN (pat, 0); i++)
22132 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22139 /* Determine if INSN stores to memory. */
22142 is_store_insn (rtx insn)
22144 if (!insn || !INSN_P (insn))
22147 return is_store_insn1 (PATTERN (insn));
22150 /* Return the dest of a store insn. */
22153 get_store_dest (rtx pat)
22155 gcc_assert (is_store_insn1 (pat));
22157 if (GET_CODE (pat) == SET)
22158 return SET_DEST (pat);
22159 else if (GET_CODE (pat) == PARALLEL)
22163 for (i = 0; i < XVECLEN (pat, 0); i++)
22165 rtx inner_pat = XVECEXP (pat, 0, i);
22166 if (GET_CODE (inner_pat) == SET
22167 && is_mem_ref (SET_DEST (inner_pat)))
22171 /* We shouldn't get here, because we should have either a simple
22172 store insn or a store with update which are covered above. */
22176 /* Returns whether the dependence between INSN and NEXT is considered
22177 costly by the given target. */
22180 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22185 /* If the flag is not enabled - no dependence is considered costly;
22186 allow all dependent insns in the same group.
22187 This is the most aggressive option. */
22188 if (rs6000_sched_costly_dep == no_dep_costly)
22191 /* If the flag is set to 1 - a dependence is always considered costly;
22192 do not allow dependent instructions in the same group.
22193 This is the most conservative option. */
22194 if (rs6000_sched_costly_dep == all_deps_costly)
22197 insn = DEP_PRO (dep);
22198 next = DEP_CON (dep);
22200 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22201 && is_load_insn (next)
22202 && is_store_insn (insn))
22203 /* Prevent load after store in the same group. */
22206 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22207 && is_load_insn (next)
22208 && is_store_insn (insn)
22209 && DEP_TYPE (dep) == REG_DEP_TRUE)
22210 /* Prevent load after store in the same group if it is a true
22214 /* The flag is set to X; dependences with latency >= X are considered costly,
22215 and will not be scheduled in the same group. */
22216 if (rs6000_sched_costly_dep <= max_dep_latency
22217 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22223 /* Return the next insn after INSN that is found before TAIL is reached,
22224 skipping any "non-active" insns - insns that will not actually occupy
22225 an issue slot. Return NULL_RTX if such an insn is not found. */
22228 get_next_active_insn (rtx insn, rtx tail)
22230 if (insn == NULL_RTX || insn == tail)
22235 insn = NEXT_INSN (insn);
22236 if (insn == NULL_RTX || insn == tail)
22241 || (NONJUMP_INSN_P (insn)
22242 && GET_CODE (PATTERN (insn)) != USE
22243 && GET_CODE (PATTERN (insn)) != CLOBBER
22244 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22250 /* We are about to begin issuing insns for this clock cycle. */
22253 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22254 rtx *ready ATTRIBUTE_UNUSED,
22255 int *pn_ready ATTRIBUTE_UNUSED,
22256 int clock_var ATTRIBUTE_UNUSED)
22258 int n_ready = *pn_ready;
22261 fprintf (dump, "// rs6000_sched_reorder :\n");
22263 /* Reorder the ready list, if the second to last ready insn
22264 is a nonepipeline insn. */
22265 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22267 if (is_nonpipeline_insn (ready[n_ready - 1])
22268 && (recog_memoized (ready[n_ready - 2]) > 0))
22269 /* Simply swap first two insns. */
22271 rtx tmp = ready[n_ready - 1];
22272 ready[n_ready - 1] = ready[n_ready - 2];
22273 ready[n_ready - 2] = tmp;
22277 if (rs6000_cpu == PROCESSOR_POWER6)
22278 load_store_pendulum = 0;
22280 return rs6000_issue_rate ();
22283 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22286 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22287 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22290 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22292 /* For Power6, we need to handle some special cases to try and keep the
22293 store queue from overflowing and triggering expensive flushes.
22295 This code monitors how load and store instructions are being issued
22296 and skews the ready list one way or the other to increase the likelihood
22297 that a desired instruction is issued at the proper time.
22299 A couple of things are done. First, we maintain a "load_store_pendulum"
22300 to track the current state of load/store issue.
22302 - If the pendulum is at zero, then no loads or stores have been
22303 issued in the current cycle so we do nothing.
22305 - If the pendulum is 1, then a single load has been issued in this
22306 cycle and we attempt to locate another load in the ready list to
22309 - If the pendulum is -2, then two stores have already been
22310 issued in this cycle, so we increase the priority of the first load
22311 in the ready list to increase it's likelihood of being chosen first
22314 - If the pendulum is -1, then a single store has been issued in this
22315 cycle and we attempt to locate another store in the ready list to
22316 issue with it, preferring a store to an adjacent memory location to
22317 facilitate store pairing in the store queue.
22319 - If the pendulum is 2, then two loads have already been
22320 issued in this cycle, so we increase the priority of the first store
22321 in the ready list to increase it's likelihood of being chosen first
22324 - If the pendulum < -2 or > 2, then do nothing.
22326 Note: This code covers the most common scenarios. There exist non
22327 load/store instructions which make use of the LSU and which
22328 would need to be accounted for to strictly model the behavior
22329 of the machine. Those instructions are currently unaccounted
22330 for to help minimize compile time overhead of this code.
22332 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22338 if (is_store_insn (last_scheduled_insn))
22339 /* Issuing a store, swing the load_store_pendulum to the left */
22340 load_store_pendulum--;
22341 else if (is_load_insn (last_scheduled_insn))
22342 /* Issuing a load, swing the load_store_pendulum to the right */
22343 load_store_pendulum++;
22345 return cached_can_issue_more;
22347 /* If the pendulum is balanced, or there is only one instruction on
22348 the ready list, then all is well, so return. */
22349 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22350 return cached_can_issue_more;
22352 if (load_store_pendulum == 1)
22354 /* A load has been issued in this cycle. Scan the ready list
22355 for another load to issue with it */
22360 if (is_load_insn (ready[pos]))
22362 /* Found a load. Move it to the head of the ready list,
22363 and adjust it's priority so that it is more likely to
22366 for (i=pos; i<*pn_ready-1; i++)
22367 ready[i] = ready[i + 1];
22368 ready[*pn_ready-1] = tmp;
22370 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22371 INSN_PRIORITY (tmp)++;
22377 else if (load_store_pendulum == -2)
22379 /* Two stores have been issued in this cycle. Increase the
22380 priority of the first load in the ready list to favor it for
22381 issuing in the next cycle. */
22386 if (is_load_insn (ready[pos])
22388 && INSN_PRIORITY_KNOWN (ready[pos]))
22390 INSN_PRIORITY (ready[pos])++;
22392 /* Adjust the pendulum to account for the fact that a load
22393 was found and increased in priority. This is to prevent
22394 increasing the priority of multiple loads */
22395 load_store_pendulum--;
22402 else if (load_store_pendulum == -1)
22404 /* A store has been issued in this cycle. Scan the ready list for
22405 another store to issue with it, preferring a store to an adjacent
22407 int first_store_pos = -1;
22413 if (is_store_insn (ready[pos]))
22415 /* Maintain the index of the first store found on the
22417 if (first_store_pos == -1)
22418 first_store_pos = pos;
22420 if (is_store_insn (last_scheduled_insn)
22421 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22423 /* Found an adjacent store. Move it to the head of the
22424 ready list, and adjust it's priority so that it is
22425 more likely to stay there */
22427 for (i=pos; i<*pn_ready-1; i++)
22428 ready[i] = ready[i + 1];
22429 ready[*pn_ready-1] = tmp;
22431 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22432 INSN_PRIORITY (tmp)++;
22434 first_store_pos = -1;
22442 if (first_store_pos >= 0)
22444 /* An adjacent store wasn't found, but a non-adjacent store was,
22445 so move the non-adjacent store to the front of the ready
22446 list, and adjust its priority so that it is more likely to
22448 tmp = ready[first_store_pos];
22449 for (i=first_store_pos; i<*pn_ready-1; i++)
22450 ready[i] = ready[i + 1];
22451 ready[*pn_ready-1] = tmp;
22452 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22453 INSN_PRIORITY (tmp)++;
22456 else if (load_store_pendulum == 2)
22458 /* Two loads have been issued in this cycle. Increase the priority
22459 of the first store in the ready list to favor it for issuing in
22465 if (is_store_insn (ready[pos])
22467 && INSN_PRIORITY_KNOWN (ready[pos]))
22469 INSN_PRIORITY (ready[pos])++;
22471 /* Adjust the pendulum to account for the fact that a store
22472 was found and increased in priority. This is to prevent
22473 increasing the priority of multiple stores */
22474 load_store_pendulum++;
22483 return cached_can_issue_more;
22486 /* Return whether the presence of INSN causes a dispatch group termination
22487 of group WHICH_GROUP.
22489 If WHICH_GROUP == current_group, this function will return true if INSN
22490 causes the termination of the current group (i.e, the dispatch group to
22491 which INSN belongs). This means that INSN will be the last insn in the
22492 group it belongs to.
22494 If WHICH_GROUP == previous_group, this function will return true if INSN
22495 causes the termination of the previous group (i.e, the dispatch group that
22496 precedes the group to which INSN belongs). This means that INSN will be
22497 the first insn in the group it belongs to). */
22500 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22507 first = insn_must_be_first_in_group (insn);
22508 last = insn_must_be_last_in_group (insn);
22513 if (which_group == current_group)
22515 else if (which_group == previous_group)
22523 insn_must_be_first_in_group (rtx insn)
22525 enum attr_type type;
22528 || GET_CODE (insn) == NOTE
22529 || DEBUG_INSN_P (insn)
22530 || GET_CODE (PATTERN (insn)) == USE
22531 || GET_CODE (PATTERN (insn)) == CLOBBER)
22534 switch (rs6000_cpu)
22536 case PROCESSOR_POWER5:
22537 if (is_cracked_insn (insn))
22539 case PROCESSOR_POWER4:
22540 if (is_microcoded_insn (insn))
22543 if (!rs6000_sched_groups)
22546 type = get_attr_type (insn);
22553 case TYPE_DELAYED_CR:
22554 case TYPE_CR_LOGICAL:
22568 case PROCESSOR_POWER6:
22569 type = get_attr_type (insn);
22573 case TYPE_INSERT_DWORD:
22577 case TYPE_VAR_SHIFT_ROTATE:
22584 case TYPE_INSERT_WORD:
22585 case TYPE_DELAYED_COMPARE:
22586 case TYPE_IMUL_COMPARE:
22587 case TYPE_LMUL_COMPARE:
22588 case TYPE_FPCOMPARE:
22599 case TYPE_LOAD_EXT_UX:
22601 case TYPE_STORE_UX:
22602 case TYPE_FPLOAD_U:
22603 case TYPE_FPLOAD_UX:
22604 case TYPE_FPSTORE_U:
22605 case TYPE_FPSTORE_UX:
22611 case PROCESSOR_POWER7:
22612 type = get_attr_type (insn);
22616 case TYPE_CR_LOGICAL:
22623 case TYPE_DELAYED_COMPARE:
22624 case TYPE_VAR_DELAYED_COMPARE:
22630 case TYPE_LOAD_EXT:
22631 case TYPE_LOAD_EXT_U:
22632 case TYPE_LOAD_EXT_UX:
22634 case TYPE_STORE_UX:
22635 case TYPE_FPLOAD_U:
22636 case TYPE_FPLOAD_UX:
22637 case TYPE_FPSTORE_U:
22638 case TYPE_FPSTORE_UX:
22654 insn_must_be_last_in_group (rtx insn)
22656 enum attr_type type;
22659 || GET_CODE (insn) == NOTE
22660 || DEBUG_INSN_P (insn)
22661 || GET_CODE (PATTERN (insn)) == USE
22662 || GET_CODE (PATTERN (insn)) == CLOBBER)
22665 switch (rs6000_cpu) {
22666 case PROCESSOR_POWER4:
22667 case PROCESSOR_POWER5:
22668 if (is_microcoded_insn (insn))
22671 if (is_branch_slot_insn (insn))
22675 case PROCESSOR_POWER6:
22676 type = get_attr_type (insn);
22683 case TYPE_VAR_SHIFT_ROTATE:
22690 case TYPE_DELAYED_COMPARE:
22691 case TYPE_IMUL_COMPARE:
22692 case TYPE_LMUL_COMPARE:
22693 case TYPE_FPCOMPARE:
22707 case PROCESSOR_POWER7:
22708 type = get_attr_type (insn);
22716 case TYPE_LOAD_EXT_U:
22717 case TYPE_LOAD_EXT_UX:
22718 case TYPE_STORE_UX:
22731 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22732 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22735 is_costly_group (rtx *group_insns, rtx next_insn)
22738 int issue_rate = rs6000_issue_rate ();
22740 for (i = 0; i < issue_rate; i++)
22742 sd_iterator_def sd_it;
22744 rtx insn = group_insns[i];
22749 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22751 rtx next = DEP_CON (dep);
22753 if (next == next_insn
22754 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22762 /* Utility of the function redefine_groups.
22763 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22764 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22765 to keep it "far" (in a separate group) from GROUP_INSNS, following
22766 one of the following schemes, depending on the value of the flag
22767 -minsert_sched_nops = X:
22768 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22769 in order to force NEXT_INSN into a separate group.
22770 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22771 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22772 insertion (has a group just ended, how many vacant issue slots remain in the
22773 last group, and how many dispatch groups were encountered so far). */
22776 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22777 rtx next_insn, bool *group_end, int can_issue_more,
22782 int issue_rate = rs6000_issue_rate ();
22783 bool end = *group_end;
22786 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22787 return can_issue_more;
22789 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22790 return can_issue_more;
22792 force = is_costly_group (group_insns, next_insn);
22794 return can_issue_more;
22796 if (sched_verbose > 6)
22797 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22798 *group_count ,can_issue_more);
22800 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22803 can_issue_more = 0;
22805 /* Since only a branch can be issued in the last issue_slot, it is
22806 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22807 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22808 in this case the last nop will start a new group and the branch
22809 will be forced to the new group. */
22810 if (can_issue_more && !is_branch_slot_insn (next_insn))
22813 while (can_issue_more > 0)
22816 emit_insn_before (nop, next_insn);
22824 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22826 int n_nops = rs6000_sched_insert_nops;
22828 /* Nops can't be issued from the branch slot, so the effective
22829 issue_rate for nops is 'issue_rate - 1'. */
22830 if (can_issue_more == 0)
22831 can_issue_more = issue_rate;
22833 if (can_issue_more == 0)
22835 can_issue_more = issue_rate - 1;
22838 for (i = 0; i < issue_rate; i++)
22840 group_insns[i] = 0;
22847 emit_insn_before (nop, next_insn);
22848 if (can_issue_more == issue_rate - 1) /* new group begins */
22851 if (can_issue_more == 0)
22853 can_issue_more = issue_rate - 1;
22856 for (i = 0; i < issue_rate; i++)
22858 group_insns[i] = 0;
22864 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22867 /* Is next_insn going to start a new group? */
22870 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22871 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22872 || (can_issue_more < issue_rate &&
22873 insn_terminates_group_p (next_insn, previous_group)));
22874 if (*group_end && end)
22877 if (sched_verbose > 6)
22878 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22879 *group_count, can_issue_more);
22880 return can_issue_more;
22883 return can_issue_more;
22886 /* This function tries to synch the dispatch groups that the compiler "sees"
22887 with the dispatch groups that the processor dispatcher is expected to
22888 form in practice. It tries to achieve this synchronization by forcing the
22889 estimated processor grouping on the compiler (as opposed to the function
22890 'pad_goups' which tries to force the scheduler's grouping on the processor).
22892 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22893 examines the (estimated) dispatch groups that will be formed by the processor
22894 dispatcher. It marks these group boundaries to reflect the estimated
22895 processor grouping, overriding the grouping that the scheduler had marked.
22896 Depending on the value of the flag '-minsert-sched-nops' this function can
22897 force certain insns into separate groups or force a certain distance between
22898 them by inserting nops, for example, if there exists a "costly dependence"
22901 The function estimates the group boundaries that the processor will form as
22902 follows: It keeps track of how many vacant issue slots are available after
22903 each insn. A subsequent insn will start a new group if one of the following
22905 - no more vacant issue slots remain in the current dispatch group.
22906 - only the last issue slot, which is the branch slot, is vacant, but the next
22907 insn is not a branch.
22908 - only the last 2 or less issue slots, including the branch slot, are vacant,
22909 which means that a cracked insn (which occupies two issue slots) can't be
22910 issued in this group.
22911 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22912 start a new group. */
22915 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22917 rtx insn, next_insn;
22919 int can_issue_more;
22922 int group_count = 0;
22926 issue_rate = rs6000_issue_rate ();
22927 group_insns = XALLOCAVEC (rtx, issue_rate);
22928 for (i = 0; i < issue_rate; i++)
22930 group_insns[i] = 0;
22932 can_issue_more = issue_rate;
22934 insn = get_next_active_insn (prev_head_insn, tail);
22937 while (insn != NULL_RTX)
22939 slot = (issue_rate - can_issue_more);
22940 group_insns[slot] = insn;
22942 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22943 if (insn_terminates_group_p (insn, current_group))
22944 can_issue_more = 0;
22946 next_insn = get_next_active_insn (insn, tail);
22947 if (next_insn == NULL_RTX)
22948 return group_count + 1;
22950 /* Is next_insn going to start a new group? */
22952 = (can_issue_more == 0
22953 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22954 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22955 || (can_issue_more < issue_rate &&
22956 insn_terminates_group_p (next_insn, previous_group)));
22958 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22959 next_insn, &group_end, can_issue_more,
22965 can_issue_more = 0;
22966 for (i = 0; i < issue_rate; i++)
22968 group_insns[i] = 0;
22972 if (GET_MODE (next_insn) == TImode && can_issue_more)
22973 PUT_MODE (next_insn, VOIDmode);
22974 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22975 PUT_MODE (next_insn, TImode);
22978 if (can_issue_more == 0)
22979 can_issue_more = issue_rate;
22982 return group_count;
22985 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22986 dispatch group boundaries that the scheduler had marked. Pad with nops
22987 any dispatch groups which have vacant issue slots, in order to force the
22988 scheduler's grouping on the processor dispatcher. The function
22989 returns the number of dispatch groups found. */
22992 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22994 rtx insn, next_insn;
22997 int can_issue_more;
22999 int group_count = 0;
23001 /* Initialize issue_rate. */
23002 issue_rate = rs6000_issue_rate ();
23003 can_issue_more = issue_rate;
23005 insn = get_next_active_insn (prev_head_insn, tail);
23006 next_insn = get_next_active_insn (insn, tail);
23008 while (insn != NULL_RTX)
23011 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23013 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23015 if (next_insn == NULL_RTX)
23020 /* If the scheduler had marked group termination at this location
23021 (between insn and next_insn), and neither insn nor next_insn will
23022 force group termination, pad the group with nops to force group
23025 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23026 && !insn_terminates_group_p (insn, current_group)
23027 && !insn_terminates_group_p (next_insn, previous_group))
23029 if (!is_branch_slot_insn (next_insn))
23032 while (can_issue_more)
23035 emit_insn_before (nop, next_insn);
23040 can_issue_more = issue_rate;
23045 next_insn = get_next_active_insn (insn, tail);
23048 return group_count;
23051 /* We're beginning a new block. Initialize data structures as necessary. */
23054 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23055 int sched_verbose ATTRIBUTE_UNUSED,
23056 int max_ready ATTRIBUTE_UNUSED)
23058 last_scheduled_insn = NULL_RTX;
23059 load_store_pendulum = 0;
23062 /* The following function is called at the end of scheduling BB.
23063 After reload, it inserts nops at insn group bundling. */
23066 rs6000_sched_finish (FILE *dump, int sched_verbose)
23071 fprintf (dump, "=== Finishing schedule.\n");
23073 if (reload_completed && rs6000_sched_groups)
23075 /* Do not run sched_finish hook when selective scheduling enabled. */
23076 if (sel_sched_p ())
23079 if (rs6000_sched_insert_nops == sched_finish_none)
23082 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23083 n_groups = pad_groups (dump, sched_verbose,
23084 current_sched_info->prev_head,
23085 current_sched_info->next_tail);
23087 n_groups = redefine_groups (dump, sched_verbose,
23088 current_sched_info->prev_head,
23089 current_sched_info->next_tail);
23091 if (sched_verbose >= 6)
23093 fprintf (dump, "ngroups = %d\n", n_groups);
23094 print_rtl (dump, current_sched_info->prev_head);
23095 fprintf (dump, "Done finish_sched\n");
23100 struct _rs6000_sched_context
23102 short cached_can_issue_more;
23103 rtx last_scheduled_insn;
23104 int load_store_pendulum;
23107 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23108 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23110 /* Allocate store for new scheduling context. */
23112 rs6000_alloc_sched_context (void)
23114 return xmalloc (sizeof (rs6000_sched_context_def));
23117 /* If CLEAN_P is true then initializes _SC with clean data,
23118 and from the global context otherwise. */
23120 rs6000_init_sched_context (void *_sc, bool clean_p)
23122 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23126 sc->cached_can_issue_more = 0;
23127 sc->last_scheduled_insn = NULL_RTX;
23128 sc->load_store_pendulum = 0;
23132 sc->cached_can_issue_more = cached_can_issue_more;
23133 sc->last_scheduled_insn = last_scheduled_insn;
23134 sc->load_store_pendulum = load_store_pendulum;
23138 /* Sets the global scheduling context to the one pointed to by _SC. */
23140 rs6000_set_sched_context (void *_sc)
23142 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23144 gcc_assert (sc != NULL);
23146 cached_can_issue_more = sc->cached_can_issue_more;
23147 last_scheduled_insn = sc->last_scheduled_insn;
23148 load_store_pendulum = sc->load_store_pendulum;
23153 rs6000_free_sched_context (void *_sc)
23155 gcc_assert (_sc != NULL);
23161 /* Length in units of the trampoline for entering a nested function. */
23164 rs6000_trampoline_size (void)
23168 switch (DEFAULT_ABI)
23171 gcc_unreachable ();
23174 ret = (TARGET_32BIT) ? 12 : 24;
23179 ret = (TARGET_32BIT) ? 40 : 48;
23186 /* Emit RTL insns to initialize the variable parts of a trampoline.
23187 FNADDR is an RTX for the address of the function's pure code.
23188 CXT is an RTX for the static chain value for the function. */
23191 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23193 int regsize = (TARGET_32BIT) ? 4 : 8;
23194 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23195 rtx ctx_reg = force_reg (Pmode, cxt);
23196 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23198 switch (DEFAULT_ABI)
23201 gcc_unreachable ();
23203 /* Under AIX, just build the 3 word function descriptor */
23206 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23207 rtx fn_reg = gen_reg_rtx (Pmode);
23208 rtx toc_reg = gen_reg_rtx (Pmode);
23210 /* Macro to shorten the code expansions below. */
23211 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23213 m_tramp = replace_equiv_address (m_tramp, addr);
23215 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23216 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23217 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23218 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23219 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23225 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23228 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23229 LCT_NORMAL, VOIDmode, 4,
23231 GEN_INT (rs6000_trampoline_size ()), SImode,
23239 /* Handle the "altivec" attribute. The attribute may have
23240 arguments as follows:
23242 __attribute__((altivec(vector__)))
23243 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23244 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23246 and may appear more than once (e.g., 'vector bool char') in a
23247 given declaration. */
23250 rs6000_handle_altivec_attribute (tree *node,
23251 tree name ATTRIBUTE_UNUSED,
23253 int flags ATTRIBUTE_UNUSED,
23254 bool *no_add_attrs)
23256 tree type = *node, result = NULL_TREE;
23257 enum machine_mode mode;
23260 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23261 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23262 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23265 while (POINTER_TYPE_P (type)
23266 || TREE_CODE (type) == FUNCTION_TYPE
23267 || TREE_CODE (type) == METHOD_TYPE
23268 || TREE_CODE (type) == ARRAY_TYPE)
23269 type = TREE_TYPE (type);
23271 mode = TYPE_MODE (type);
23273 /* Check for invalid AltiVec type qualifiers. */
23274 if (type == long_double_type_node)
23275 error ("use of %<long double%> in AltiVec types is invalid");
23276 else if (type == boolean_type_node)
23277 error ("use of boolean types in AltiVec types is invalid");
23278 else if (TREE_CODE (type) == COMPLEX_TYPE)
23279 error ("use of %<complex%> in AltiVec types is invalid");
23280 else if (DECIMAL_FLOAT_MODE_P (mode))
23281 error ("use of decimal floating point types in AltiVec types is invalid");
23282 else if (!TARGET_VSX)
23284 if (type == long_unsigned_type_node || type == long_integer_type_node)
23287 error ("use of %<long%> in AltiVec types is invalid for "
23288 "64-bit code without -mvsx");
23289 else if (rs6000_warn_altivec_long)
23290 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23293 else if (type == long_long_unsigned_type_node
23294 || type == long_long_integer_type_node)
23295 error ("use of %<long long%> in AltiVec types is invalid without "
23297 else if (type == double_type_node)
23298 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23301 switch (altivec_type)
23304 unsigned_p = TYPE_UNSIGNED (type);
23308 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23311 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23314 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23317 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23319 case SFmode: result = V4SF_type_node; break;
23320 case DFmode: result = V2DF_type_node; break;
23321 /* If the user says 'vector int bool', we may be handed the 'bool'
23322 attribute _before_ the 'vector' attribute, and so select the
23323 proper type in the 'b' case below. */
23324 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23325 case V2DImode: case V2DFmode:
23333 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23334 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23335 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23336 case QImode: case V16QImode: result = bool_V16QI_type_node;
23343 case V8HImode: result = pixel_V8HI_type_node;
23349 /* Propagate qualifiers attached to the element type
23350 onto the vector type. */
23351 if (result && result != type && TYPE_QUALS (type))
23352 result = build_qualified_type (result, TYPE_QUALS (type));
23354 *no_add_attrs = true; /* No need to hang on to the attribute. */
23357 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23362 /* AltiVec defines four built-in scalar types that serve as vector
23363 elements; we must teach the compiler how to mangle them. */
23365 static const char *
23366 rs6000_mangle_type (const_tree type)
23368 type = TYPE_MAIN_VARIANT (type);
23370 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23371 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23374 if (type == bool_char_type_node) return "U6__boolc";
23375 if (type == bool_short_type_node) return "U6__bools";
23376 if (type == pixel_type_node) return "u7__pixel";
23377 if (type == bool_int_type_node) return "U6__booli";
23378 if (type == bool_long_type_node) return "U6__booll";
23380 /* Mangle IBM extended float long double as `g' (__float128) on
23381 powerpc*-linux where long-double-64 previously was the default. */
23382 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23384 && TARGET_LONG_DOUBLE_128
23385 && !TARGET_IEEEQUAD)
23388 /* For all other types, use normal C++ mangling. */
23392 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23393 struct attribute_spec.handler. */
23396 rs6000_handle_longcall_attribute (tree *node, tree name,
23397 tree args ATTRIBUTE_UNUSED,
23398 int flags ATTRIBUTE_UNUSED,
23399 bool *no_add_attrs)
23401 if (TREE_CODE (*node) != FUNCTION_TYPE
23402 && TREE_CODE (*node) != FIELD_DECL
23403 && TREE_CODE (*node) != TYPE_DECL)
23405 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23407 *no_add_attrs = true;
23413 /* Set longcall attributes on all functions declared when
23414 rs6000_default_long_calls is true. */
23416 rs6000_set_default_type_attributes (tree type)
23418 if (rs6000_default_long_calls
23419 && (TREE_CODE (type) == FUNCTION_TYPE
23420 || TREE_CODE (type) == METHOD_TYPE))
23421 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23423 TYPE_ATTRIBUTES (type));
23426 darwin_set_default_type_attributes (type);
23430 /* Return a reference suitable for calling a function with the
23431 longcall attribute. */
23434 rs6000_longcall_ref (rtx call_ref)
23436 const char *call_name;
23439 if (GET_CODE (call_ref) != SYMBOL_REF)
23442 /* System V adds '.' to the internal name, so skip them. */
23443 call_name = XSTR (call_ref, 0);
23444 if (*call_name == '.')
23446 while (*call_name == '.')
23449 node = get_identifier (call_name);
23450 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23453 return force_reg (Pmode, call_ref);
23456 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23457 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23460 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23461 struct attribute_spec.handler. */
23463 rs6000_handle_struct_attribute (tree *node, tree name,
23464 tree args ATTRIBUTE_UNUSED,
23465 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23468 if (DECL_P (*node))
23470 if (TREE_CODE (*node) == TYPE_DECL)
23471 type = &TREE_TYPE (*node);
23476 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23477 || TREE_CODE (*type) == UNION_TYPE)))
23479 warning (OPT_Wattributes, "%qE attribute ignored", name);
23480 *no_add_attrs = true;
23483 else if ((is_attribute_p ("ms_struct", name)
23484 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23485 || ((is_attribute_p ("gcc_struct", name)
23486 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23488 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23490 *no_add_attrs = true;
23497 rs6000_ms_bitfield_layout_p (const_tree record_type)
23499 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23500 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23501 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23504 #ifdef USING_ELFOS_H
23506 /* A get_unnamed_section callback, used for switching to toc_section. */
23509 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23511 if (DEFAULT_ABI == ABI_AIX
23512 && TARGET_MINIMAL_TOC
23513 && !TARGET_RELOCATABLE)
23515 if (!toc_initialized)
23517 toc_initialized = 1;
23518 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23519 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23520 fprintf (asm_out_file, "\t.tc ");
23521 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23522 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23523 fprintf (asm_out_file, "\n");
23525 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23526 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23527 fprintf (asm_out_file, " = .+32768\n");
23530 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23532 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23533 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23536 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23537 if (!toc_initialized)
23539 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23540 fprintf (asm_out_file, " = .+32768\n");
23541 toc_initialized = 1;
23546 /* Implement TARGET_ASM_INIT_SECTIONS. */
23549 rs6000_elf_asm_init_sections (void)
23552 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23555 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23556 SDATA2_SECTION_ASM_OP);
23559 /* Implement TARGET_SELECT_RTX_SECTION. */
23562 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23563 unsigned HOST_WIDE_INT align)
23565 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23566 return toc_section;
23568 return default_elf_select_rtx_section (mode, x, align);
23571 /* For a SYMBOL_REF, set generic flags and then perform some
23572 target-specific processing.
23574 When the AIX ABI is requested on a non-AIX system, replace the
23575 function name with the real name (with a leading .) rather than the
23576 function descriptor name. This saves a lot of overriding code to
23577 read the prefixes. */
23580 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23582 default_encode_section_info (decl, rtl, first);
23585 && TREE_CODE (decl) == FUNCTION_DECL
23587 && DEFAULT_ABI == ABI_AIX)
23589 rtx sym_ref = XEXP (rtl, 0);
23590 size_t len = strlen (XSTR (sym_ref, 0));
23591 char *str = XALLOCAVEC (char, len + 2);
23593 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23594 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23599 compare_section_name (const char *section, const char *templ)
23603 len = strlen (templ);
23604 return (strncmp (section, templ, len) == 0
23605 && (section[len] == 0 || section[len] == '.'));
23609 rs6000_elf_in_small_data_p (const_tree decl)
23611 if (rs6000_sdata == SDATA_NONE)
23614 /* We want to merge strings, so we never consider them small data. */
23615 if (TREE_CODE (decl) == STRING_CST)
23618 /* Functions are never in the small data area. */
23619 if (TREE_CODE (decl) == FUNCTION_DECL)
23622 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23624 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23625 if (compare_section_name (section, ".sdata")
23626 || compare_section_name (section, ".sdata2")
23627 || compare_section_name (section, ".gnu.linkonce.s")
23628 || compare_section_name (section, ".sbss")
23629 || compare_section_name (section, ".sbss2")
23630 || compare_section_name (section, ".gnu.linkonce.sb")
23631 || strcmp (section, ".PPC.EMB.sdata0") == 0
23632 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23637 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23640 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23641 /* If it's not public, and we're not going to reference it there,
23642 there's no need to put it in the small data section. */
23643 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23650 #endif /* USING_ELFOS_H */
23652 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23655 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23657 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23660 /* Return a REG that occurs in ADDR with coefficient 1.
23661 ADDR can be effectively incremented by incrementing REG.
23663 r0 is special and we must not select it as an address
23664 register by this routine since our caller will try to
23665 increment the returned register via an "la" instruction. */
23668 find_addr_reg (rtx addr)
23670 while (GET_CODE (addr) == PLUS)
23672 if (GET_CODE (XEXP (addr, 0)) == REG
23673 && REGNO (XEXP (addr, 0)) != 0)
23674 addr = XEXP (addr, 0);
23675 else if (GET_CODE (XEXP (addr, 1)) == REG
23676 && REGNO (XEXP (addr, 1)) != 0)
23677 addr = XEXP (addr, 1);
23678 else if (CONSTANT_P (XEXP (addr, 0)))
23679 addr = XEXP (addr, 1);
23680 else if (CONSTANT_P (XEXP (addr, 1)))
23681 addr = XEXP (addr, 0);
23683 gcc_unreachable ();
23685 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23690 rs6000_fatal_bad_address (rtx op)
23692 fatal_insn ("bad address", op);
23697 static tree branch_island_list = 0;
23699 /* Remember to generate a branch island for far calls to the given
23703 add_compiler_branch_island (tree label_name, tree function_name,
23706 tree branch_island = build_tree_list (function_name, label_name);
23707 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23708 TREE_CHAIN (branch_island) = branch_island_list;
23709 branch_island_list = branch_island;
23712 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23713 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23714 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23715 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23717 /* Generate far-jump branch islands for everything on the
23718 branch_island_list. Invoked immediately after the last instruction
23719 of the epilogue has been emitted; the branch-islands must be
23720 appended to, and contiguous with, the function body. Mach-O stubs
23721 are generated in machopic_output_stub(). */
23724 macho_branch_islands (void)
23727 tree branch_island;
23729 for (branch_island = branch_island_list;
23731 branch_island = TREE_CHAIN (branch_island))
23733 const char *label =
23734 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23736 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23737 char name_buf[512];
23738 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23739 if (name[0] == '*' || name[0] == '&')
23740 strcpy (name_buf, name+1);
23744 strcpy (name_buf+1, name);
23746 strcpy (tmp_buf, "\n");
23747 strcat (tmp_buf, label);
23748 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23749 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23750 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23751 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23754 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23755 strcat (tmp_buf, label);
23756 strcat (tmp_buf, "_pic\n");
23757 strcat (tmp_buf, label);
23758 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23760 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23761 strcat (tmp_buf, name_buf);
23762 strcat (tmp_buf, " - ");
23763 strcat (tmp_buf, label);
23764 strcat (tmp_buf, "_pic)\n");
23766 strcat (tmp_buf, "\tmtlr r0\n");
23768 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23769 strcat (tmp_buf, name_buf);
23770 strcat (tmp_buf, " - ");
23771 strcat (tmp_buf, label);
23772 strcat (tmp_buf, "_pic)\n");
23774 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23778 strcat (tmp_buf, ":\nlis r12,hi16(");
23779 strcat (tmp_buf, name_buf);
23780 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23781 strcat (tmp_buf, name_buf);
23782 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23784 output_asm_insn (tmp_buf, 0);
23785 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23786 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23787 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23788 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23791 branch_island_list = 0;
23794 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23795 already there or not. */
23798 no_previous_def (tree function_name)
23800 tree branch_island;
23801 for (branch_island = branch_island_list;
23803 branch_island = TREE_CHAIN (branch_island))
23804 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23809 /* GET_PREV_LABEL gets the label name from the previous definition of
23813 get_prev_label (tree function_name)
23815 tree branch_island;
23816 for (branch_island = branch_island_list;
23818 branch_island = TREE_CHAIN (branch_island))
23819 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23820 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23824 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23825 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23828 /* KEXTs still need branch islands. */
23829 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23830 || flag_mkernel || flag_apple_kext)
23832 /* INSN is either a function call or a millicode call. It may have an
23833 unconditional jump in its delay slot.
23835 CALL_DEST is the routine we are calling. */
23838 output_call (rtx insn, rtx *operands, int dest_operand_number,
23839 int cookie_operand_number)
23841 static char buf[256];
23842 if (DARWIN_GENERATE_ISLANDS
23843 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23844 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23847 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23849 if (no_previous_def (funname))
23851 rtx label_rtx = gen_label_rtx ();
23852 char *label_buf, temp_buf[256];
23853 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23854 CODE_LABEL_NUMBER (label_rtx));
23855 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23856 labelname = get_identifier (label_buf);
23857 add_compiler_branch_island (labelname, funname, insn_line (insn));
23860 labelname = get_prev_label (funname);
23862 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23863 instruction will reach 'foo', otherwise link as 'bl L42'".
23864 "L42" should be a 'branch island', that will do a far jump to
23865 'foo'. Branch islands are generated in
23866 macho_branch_islands(). */
23867 sprintf (buf, "jbsr %%z%d,%.246s",
23868 dest_operand_number, IDENTIFIER_POINTER (labelname));
23871 sprintf (buf, "bl %%z%d", dest_operand_number);
23875 /* Generate PIC and indirect symbol stubs. */
23878 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23880 unsigned int length;
23881 char *symbol_name, *lazy_ptr_name;
23882 char *local_label_0;
23883 static int label = 0;
23885 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23886 symb = (*targetm.strip_name_encoding) (symb);
23889 length = strlen (symb);
23890 symbol_name = XALLOCAVEC (char, length + 32);
23891 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23893 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23894 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23897 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23899 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23903 fprintf (file, "\t.align 5\n");
23905 fprintf (file, "%s:\n", stub);
23906 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23909 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23910 sprintf (local_label_0, "\"L%011d$spb\"", label);
23912 fprintf (file, "\tmflr r0\n");
23913 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23914 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23915 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23916 lazy_ptr_name, local_label_0);
23917 fprintf (file, "\tmtlr r0\n");
23918 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23919 (TARGET_64BIT ? "ldu" : "lwzu"),
23920 lazy_ptr_name, local_label_0);
23921 fprintf (file, "\tmtctr r12\n");
23922 fprintf (file, "\tbctr\n");
23926 fprintf (file, "\t.align 4\n");
23928 fprintf (file, "%s:\n", stub);
23929 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23931 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23932 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23933 (TARGET_64BIT ? "ldu" : "lwzu"),
23935 fprintf (file, "\tmtctr r12\n");
23936 fprintf (file, "\tbctr\n");
23939 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23940 fprintf (file, "%s:\n", lazy_ptr_name);
23941 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23942 fprintf (file, "%sdyld_stub_binding_helper\n",
23943 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23946 /* Legitimize PIC addresses. If the address is already
23947 position-independent, we return ORIG. Newly generated
23948 position-independent addresses go into a reg. This is REG if non
23949 zero, otherwise we allocate register(s) as necessary. */
23951 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23954 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23959 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23960 reg = gen_reg_rtx (Pmode);
23962 if (GET_CODE (orig) == CONST)
23966 if (GET_CODE (XEXP (orig, 0)) == PLUS
23967 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23970 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23972 /* Use a different reg for the intermediate value, as
23973 it will be marked UNCHANGING. */
23974 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23975 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23978 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23981 if (GET_CODE (offset) == CONST_INT)
23983 if (SMALL_INT (offset))
23984 return plus_constant (base, INTVAL (offset));
23985 else if (! reload_in_progress && ! reload_completed)
23986 offset = force_reg (Pmode, offset);
23989 rtx mem = force_const_mem (Pmode, orig);
23990 return machopic_legitimize_pic_address (mem, Pmode, reg);
23993 return gen_rtx_PLUS (Pmode, base, offset);
23996 /* Fall back on generic machopic code. */
23997 return machopic_legitimize_pic_address (orig, mode, reg);
24000 /* Output a .machine directive for the Darwin assembler, and call
24001 the generic start_file routine. */
24004 rs6000_darwin_file_start (void)
24006 static const struct
24012 { "ppc64", "ppc64", MASK_64BIT },
24013 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24014 { "power4", "ppc970", 0 },
24015 { "G5", "ppc970", 0 },
24016 { "7450", "ppc7450", 0 },
24017 { "7400", "ppc7400", MASK_ALTIVEC },
24018 { "G4", "ppc7400", 0 },
24019 { "750", "ppc750", 0 },
24020 { "740", "ppc750", 0 },
24021 { "G3", "ppc750", 0 },
24022 { "604e", "ppc604e", 0 },
24023 { "604", "ppc604", 0 },
24024 { "603e", "ppc603", 0 },
24025 { "603", "ppc603", 0 },
24026 { "601", "ppc601", 0 },
24027 { NULL, "ppc", 0 } };
24028 const char *cpu_id = "";
24031 rs6000_file_start ();
24032 darwin_file_start ();
24034 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24035 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24036 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24037 && rs6000_select[i].string[0] != '\0')
24038 cpu_id = rs6000_select[i].string;
24040 /* Look through the mapping array. Pick the first name that either
24041 matches the argument, has a bit set in IF_SET that is also set
24042 in the target flags, or has a NULL name. */
24045 while (mapping[i].arg != NULL
24046 && strcmp (mapping[i].arg, cpu_id) != 0
24047 && (mapping[i].if_set & target_flags) == 0)
24050 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24053 #endif /* TARGET_MACHO */
24057 rs6000_elf_reloc_rw_mask (void)
24061 else if (DEFAULT_ABI == ABI_AIX)
24067 /* Record an element in the table of global constructors. SYMBOL is
24068 a SYMBOL_REF of the function to be called; PRIORITY is a number
24069 between 0 and MAX_INIT_PRIORITY.
24071 This differs from default_named_section_asm_out_constructor in
24072 that we have special handling for -mrelocatable. */
24075 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24077 const char *section = ".ctors";
24080 if (priority != DEFAULT_INIT_PRIORITY)
24082 sprintf (buf, ".ctors.%.5u",
24083 /* Invert the numbering so the linker puts us in the proper
24084 order; constructors are run from right to left, and the
24085 linker sorts in increasing order. */
24086 MAX_INIT_PRIORITY - priority);
24090 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24091 assemble_align (POINTER_SIZE);
24093 if (TARGET_RELOCATABLE)
24095 fputs ("\t.long (", asm_out_file);
24096 output_addr_const (asm_out_file, symbol);
24097 fputs (")@fixup\n", asm_out_file);
24100 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24104 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24106 const char *section = ".dtors";
24109 if (priority != DEFAULT_INIT_PRIORITY)
24111 sprintf (buf, ".dtors.%.5u",
24112 /* Invert the numbering so the linker puts us in the proper
24113 order; constructors are run from right to left, and the
24114 linker sorts in increasing order. */
24115 MAX_INIT_PRIORITY - priority);
24119 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24120 assemble_align (POINTER_SIZE);
24122 if (TARGET_RELOCATABLE)
24124 fputs ("\t.long (", asm_out_file);
24125 output_addr_const (asm_out_file, symbol);
24126 fputs (")@fixup\n", asm_out_file);
24129 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24133 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24137 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24138 ASM_OUTPUT_LABEL (file, name);
24139 fputs (DOUBLE_INT_ASM_OP, file);
24140 rs6000_output_function_entry (file, name);
24141 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24144 fputs ("\t.size\t", file);
24145 assemble_name (file, name);
24146 fputs (",24\n\t.type\t.", file);
24147 assemble_name (file, name);
24148 fputs (",@function\n", file);
24149 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24151 fputs ("\t.globl\t.", file);
24152 assemble_name (file, name);
24157 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24158 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24159 rs6000_output_function_entry (file, name);
24160 fputs (":\n", file);
24164 if (TARGET_RELOCATABLE
24165 && !TARGET_SECURE_PLT
24166 && (get_pool_size () != 0 || crtl->profile)
24171 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24173 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24174 fprintf (file, "\t.long ");
24175 assemble_name (file, buf);
24177 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24178 assemble_name (file, buf);
24182 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24183 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24185 if (DEFAULT_ABI == ABI_AIX)
24187 const char *desc_name, *orig_name;
24189 orig_name = (*targetm.strip_name_encoding) (name);
24190 desc_name = orig_name;
24191 while (*desc_name == '.')
24194 if (TREE_PUBLIC (decl))
24195 fprintf (file, "\t.globl %s\n", desc_name);
24197 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24198 fprintf (file, "%s:\n", desc_name);
24199 fprintf (file, "\t.long %s\n", orig_name);
24200 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24201 if (DEFAULT_ABI == ABI_AIX)
24202 fputs ("\t.long 0\n", file);
24203 fprintf (file, "\t.previous\n");
24205 ASM_OUTPUT_LABEL (file, name);
24209 rs6000_elf_end_indicate_exec_stack (void)
24212 file_end_indicate_exec_stack ();
24218 rs6000_xcoff_asm_output_anchor (rtx symbol)
24222 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24223 SYMBOL_REF_BLOCK_OFFSET (symbol));
24224 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24228 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24230 fputs (GLOBAL_ASM_OP, stream);
24231 RS6000_OUTPUT_BASENAME (stream, name);
24232 putc ('\n', stream);
24235 /* A get_unnamed_decl callback, used for read-only sections. PTR
24236 points to the section string variable. */
24239 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24241 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24242 *(const char *const *) directive,
24243 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24246 /* Likewise for read-write sections. */
24249 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24251 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24252 *(const char *const *) directive,
24253 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24256 /* A get_unnamed_section callback, used for switching to toc_section. */
24259 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24261 if (TARGET_MINIMAL_TOC)
24263 /* toc_section is always selected at least once from
24264 rs6000_xcoff_file_start, so this is guaranteed to
24265 always be defined once and only once in each file. */
24266 if (!toc_initialized)
24268 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24269 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24270 toc_initialized = 1;
24272 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24273 (TARGET_32BIT ? "" : ",3"));
24276 fputs ("\t.toc\n", asm_out_file);
24279 /* Implement TARGET_ASM_INIT_SECTIONS. */
24282 rs6000_xcoff_asm_init_sections (void)
24284 read_only_data_section
24285 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24286 &xcoff_read_only_section_name);
24288 private_data_section
24289 = get_unnamed_section (SECTION_WRITE,
24290 rs6000_xcoff_output_readwrite_section_asm_op,
24291 &xcoff_private_data_section_name);
24293 read_only_private_data_section
24294 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24295 &xcoff_private_data_section_name);
24298 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24300 readonly_data_section = read_only_data_section;
24301 exception_section = data_section;
24305 rs6000_xcoff_reloc_rw_mask (void)
24311 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24312 tree decl ATTRIBUTE_UNUSED)
24315 static const char * const suffix[3] = { "PR", "RO", "RW" };
24317 if (flags & SECTION_CODE)
24319 else if (flags & SECTION_WRITE)
24324 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24325 (flags & SECTION_CODE) ? "." : "",
24326 name, suffix[smclass], flags & SECTION_ENTSIZE);
24330 rs6000_xcoff_select_section (tree decl, int reloc,
24331 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24333 if (decl_readonly_section (decl, reloc))
24335 if (TREE_PUBLIC (decl))
24336 return read_only_data_section;
24338 return read_only_private_data_section;
24342 if (TREE_PUBLIC (decl))
24343 return data_section;
24345 return private_data_section;
24350 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24354 /* Use select_section for private and uninitialized data. */
24355 if (!TREE_PUBLIC (decl)
24356 || DECL_COMMON (decl)
24357 || DECL_INITIAL (decl) == NULL_TREE
24358 || DECL_INITIAL (decl) == error_mark_node
24359 || (flag_zero_initialized_in_bss
24360 && initializer_zerop (DECL_INITIAL (decl))))
24363 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24364 name = (*targetm.strip_name_encoding) (name);
24365 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24368 /* Select section for constant in constant pool.
24370 On RS/6000, all constants are in the private read-only data area.
24371 However, if this is being placed in the TOC it must be output as a
24375 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24376 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24378 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24379 return toc_section;
24381 return read_only_private_data_section;
24384 /* Remove any trailing [DS] or the like from the symbol name. */
24386 static const char *
24387 rs6000_xcoff_strip_name_encoding (const char *name)
24392 len = strlen (name);
24393 if (name[len - 1] == ']')
24394 return ggc_alloc_string (name, len - 4);
24399 /* Section attributes. AIX is always PIC. */
24401 static unsigned int
24402 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24404 unsigned int align;
24405 unsigned int flags = default_section_type_flags (decl, name, reloc);
24407 /* Align to at least UNIT size. */
24408 if (flags & SECTION_CODE)
24409 align = MIN_UNITS_PER_WORD;
24411 /* Increase alignment of large objects if not already stricter. */
24412 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24413 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24414 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24416 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24419 /* Output at beginning of assembler file.
24421 Initialize the section names for the RS/6000 at this point.
24423 Specify filename, including full path, to assembler.
24425 We want to go into the TOC section so at least one .toc will be emitted.
24426 Also, in order to output proper .bs/.es pairs, we need at least one static
24427 [RW] section emitted.
24429 Finally, declare mcount when profiling to make the assembler happy. */
24432 rs6000_xcoff_file_start (void)
24434 rs6000_gen_section_name (&xcoff_bss_section_name,
24435 main_input_filename, ".bss_");
24436 rs6000_gen_section_name (&xcoff_private_data_section_name,
24437 main_input_filename, ".rw_");
24438 rs6000_gen_section_name (&xcoff_read_only_section_name,
24439 main_input_filename, ".ro_");
24441 fputs ("\t.file\t", asm_out_file);
24442 output_quoted_string (asm_out_file, main_input_filename);
24443 fputc ('\n', asm_out_file);
24444 if (write_symbols != NO_DEBUG)
24445 switch_to_section (private_data_section);
24446 switch_to_section (text_section);
24448 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24449 rs6000_file_start ();
24452 /* Output at end of assembler file.
24453 On the RS/6000, referencing data should automatically pull in text. */
24456 rs6000_xcoff_file_end (void)
24458 switch_to_section (text_section);
24459 fputs ("_section_.text:\n", asm_out_file);
24460 switch_to_section (data_section);
24461 fputs (TARGET_32BIT
24462 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24465 #endif /* TARGET_XCOFF */
24467 /* Compute a (partial) cost for rtx X. Return true if the complete
24468 cost has been computed, and false if subexpressions should be
24469 scanned. In either case, *TOTAL contains the cost result. */
24472 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24475 enum machine_mode mode = GET_MODE (x);
24479 /* On the RS/6000, if it is valid in the insn, it is free. */
24481 if (((outer_code == SET
24482 || outer_code == PLUS
24483 || outer_code == MINUS)
24484 && (satisfies_constraint_I (x)
24485 || satisfies_constraint_L (x)))
24486 || (outer_code == AND
24487 && (satisfies_constraint_K (x)
24489 ? satisfies_constraint_L (x)
24490 : satisfies_constraint_J (x))
24491 || mask_operand (x, mode)
24493 && mask64_operand (x, DImode))))
24494 || ((outer_code == IOR || outer_code == XOR)
24495 && (satisfies_constraint_K (x)
24497 ? satisfies_constraint_L (x)
24498 : satisfies_constraint_J (x))))
24499 || outer_code == ASHIFT
24500 || outer_code == ASHIFTRT
24501 || outer_code == LSHIFTRT
24502 || outer_code == ROTATE
24503 || outer_code == ROTATERT
24504 || outer_code == ZERO_EXTRACT
24505 || (outer_code == MULT
24506 && satisfies_constraint_I (x))
24507 || ((outer_code == DIV || outer_code == UDIV
24508 || outer_code == MOD || outer_code == UMOD)
24509 && exact_log2 (INTVAL (x)) >= 0)
24510 || (outer_code == COMPARE
24511 && (satisfies_constraint_I (x)
24512 || satisfies_constraint_K (x)))
24513 || (outer_code == EQ
24514 && (satisfies_constraint_I (x)
24515 || satisfies_constraint_K (x)
24517 ? satisfies_constraint_L (x)
24518 : satisfies_constraint_J (x))))
24519 || (outer_code == GTU
24520 && satisfies_constraint_I (x))
24521 || (outer_code == LTU
24522 && satisfies_constraint_P (x)))
24527 else if ((outer_code == PLUS
24528 && reg_or_add_cint_operand (x, VOIDmode))
24529 || (outer_code == MINUS
24530 && reg_or_sub_cint_operand (x, VOIDmode))
24531 || ((outer_code == SET
24532 || outer_code == IOR
24533 || outer_code == XOR)
24535 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24537 *total = COSTS_N_INSNS (1);
24543 if (mode == DImode && code == CONST_DOUBLE)
24545 if ((outer_code == IOR || outer_code == XOR)
24546 && CONST_DOUBLE_HIGH (x) == 0
24547 && (CONST_DOUBLE_LOW (x)
24548 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24553 else if ((outer_code == AND && and64_2_operand (x, DImode))
24554 || ((outer_code == SET
24555 || outer_code == IOR
24556 || outer_code == XOR)
24557 && CONST_DOUBLE_HIGH (x) == 0))
24559 *total = COSTS_N_INSNS (1);
24569 /* When optimizing for size, MEM should be slightly more expensive
24570 than generating address, e.g., (plus (reg) (const)).
24571 L1 cache latency is about two instructions. */
24572 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24580 if (mode == DFmode)
24582 if (GET_CODE (XEXP (x, 0)) == MULT)
24584 /* FNMA accounted in outer NEG. */
24585 if (outer_code == NEG)
24586 *total = rs6000_cost->dmul - rs6000_cost->fp;
24588 *total = rs6000_cost->dmul;
24591 *total = rs6000_cost->fp;
24593 else if (mode == SFmode)
24595 /* FNMA accounted in outer NEG. */
24596 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24599 *total = rs6000_cost->fp;
24602 *total = COSTS_N_INSNS (1);
24606 if (mode == DFmode)
24608 if (GET_CODE (XEXP (x, 0)) == MULT
24609 || GET_CODE (XEXP (x, 1)) == MULT)
24611 /* FNMA accounted in outer NEG. */
24612 if (outer_code == NEG)
24613 *total = rs6000_cost->dmul - rs6000_cost->fp;
24615 *total = rs6000_cost->dmul;
24618 *total = rs6000_cost->fp;
24620 else if (mode == SFmode)
24622 /* FNMA accounted in outer NEG. */
24623 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24626 *total = rs6000_cost->fp;
24629 *total = COSTS_N_INSNS (1);
24633 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24634 && satisfies_constraint_I (XEXP (x, 1)))
24636 if (INTVAL (XEXP (x, 1)) >= -256
24637 && INTVAL (XEXP (x, 1)) <= 255)
24638 *total = rs6000_cost->mulsi_const9;
24640 *total = rs6000_cost->mulsi_const;
24642 /* FMA accounted in outer PLUS/MINUS. */
24643 else if ((mode == DFmode || mode == SFmode)
24644 && (outer_code == PLUS || outer_code == MINUS))
24646 else if (mode == DFmode)
24647 *total = rs6000_cost->dmul;
24648 else if (mode == SFmode)
24649 *total = rs6000_cost->fp;
24650 else if (mode == DImode)
24651 *total = rs6000_cost->muldi;
24653 *total = rs6000_cost->mulsi;
24658 if (FLOAT_MODE_P (mode))
24660 *total = mode == DFmode ? rs6000_cost->ddiv
24661 : rs6000_cost->sdiv;
24668 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24669 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24671 if (code == DIV || code == MOD)
24673 *total = COSTS_N_INSNS (2);
24676 *total = COSTS_N_INSNS (1);
24680 if (GET_MODE (XEXP (x, 1)) == DImode)
24681 *total = rs6000_cost->divdi;
24683 *total = rs6000_cost->divsi;
24685 /* Add in shift and subtract for MOD. */
24686 if (code == MOD || code == UMOD)
24687 *total += COSTS_N_INSNS (2);
24692 *total = COSTS_N_INSNS (4);
24696 *total = COSTS_N_INSNS (6);
24700 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24712 *total = COSTS_N_INSNS (1);
24720 /* Handle mul_highpart. */
24721 if (outer_code == TRUNCATE
24722 && GET_CODE (XEXP (x, 0)) == MULT)
24724 if (mode == DImode)
24725 *total = rs6000_cost->muldi;
24727 *total = rs6000_cost->mulsi;
24730 else if (outer_code == AND)
24733 *total = COSTS_N_INSNS (1);
24738 if (GET_CODE (XEXP (x, 0)) == MEM)
24741 *total = COSTS_N_INSNS (1);
24747 if (!FLOAT_MODE_P (mode))
24749 *total = COSTS_N_INSNS (1);
24755 case UNSIGNED_FLOAT:
24758 case FLOAT_TRUNCATE:
24759 *total = rs6000_cost->fp;
24763 if (mode == DFmode)
24766 *total = rs6000_cost->fp;
24770 switch (XINT (x, 1))
24773 *total = rs6000_cost->fp;
24785 *total = COSTS_N_INSNS (1);
24788 else if (FLOAT_MODE_P (mode)
24789 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24791 *total = rs6000_cost->fp;
24799 /* Carry bit requires mode == Pmode.
24800 NEG or PLUS already counted so only add one. */
24802 && (outer_code == NEG || outer_code == PLUS))
24804 *total = COSTS_N_INSNS (1);
24807 if (outer_code == SET)
24809 if (XEXP (x, 1) == const0_rtx)
24811 if (TARGET_ISEL && !TARGET_MFCRF)
24812 *total = COSTS_N_INSNS (8);
24814 *total = COSTS_N_INSNS (2);
24817 else if (mode == Pmode)
24819 *total = COSTS_N_INSNS (3);
24828 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24830 if (TARGET_ISEL && !TARGET_MFCRF)
24831 *total = COSTS_N_INSNS (8);
24833 *total = COSTS_N_INSNS (2);
24837 if (outer_code == COMPARE)
24851 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24854 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24857 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24860 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24861 "total = %d, speed = %s, x:\n",
24862 ret ? "complete" : "scan inner",
24863 GET_RTX_NAME (code),
24864 GET_RTX_NAME (outer_code),
24866 speed ? "true" : "false");
24873 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24876 rs6000_debug_address_cost (rtx x, bool speed)
24878 int ret = TARGET_ADDRESS_COST (x, speed);
24880 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24881 ret, speed ? "true" : "false");
24888 /* A C expression returning the cost of moving data from a register of class
24889 CLASS1 to one of CLASS2. */
24892 rs6000_register_move_cost (enum machine_mode mode,
24893 enum reg_class from, enum reg_class to)
24897 /* Moves from/to GENERAL_REGS. */
24898 if (reg_classes_intersect_p (to, GENERAL_REGS)
24899 || reg_classes_intersect_p (from, GENERAL_REGS))
24901 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24904 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24905 ret = (rs6000_memory_move_cost (mode, from, 0)
24906 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24908 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24910 else if (from == CR_REGS)
24913 /* Power6 has slower LR/CTR moves so make them more expensive than
24914 memory in order to bias spills to memory .*/
24915 else if (rs6000_cpu == PROCESSOR_POWER6
24916 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24917 ret = 6 * hard_regno_nregs[0][mode];
24920 /* A move will cost one instruction per GPR moved. */
24921 ret = 2 * hard_regno_nregs[0][mode];
24924 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24925 else if (VECTOR_UNIT_VSX_P (mode)
24926 && reg_classes_intersect_p (to, VSX_REGS)
24927 && reg_classes_intersect_p (from, VSX_REGS))
24928 ret = 2 * hard_regno_nregs[32][mode];
24930 /* Moving between two similar registers is just one instruction. */
24931 else if (reg_classes_intersect_p (to, from))
24932 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24934 /* Everything else has to go through GENERAL_REGS. */
24936 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24937 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24939 if (TARGET_DEBUG_COST)
24941 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24942 ret, GET_MODE_NAME (mode), reg_class_names[from],
24943 reg_class_names[to]);
24948 /* A C expressions returning the cost of moving data of MODE from a register to
24952 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24953 int in ATTRIBUTE_UNUSED)
24957 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24958 ret = 4 * hard_regno_nregs[0][mode];
24959 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24960 ret = 4 * hard_regno_nregs[32][mode];
24961 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24962 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24964 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24966 if (TARGET_DEBUG_COST)
24968 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24969 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24974 /* Returns a code for a target-specific builtin that implements
24975 reciprocal of the function, or NULL_TREE if not available. */
24978 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24979 bool sqrt ATTRIBUTE_UNUSED)
24981 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24982 && flag_finite_math_only && !flag_trapping_math
24983 && flag_unsafe_math_optimizations))
24991 case BUILT_IN_SQRTF:
24992 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24999 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25000 Assumes no trapping math and finite arguments. */
25003 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25005 rtx x0, e0, e1, y1, u0, v0, one;
25007 x0 = gen_reg_rtx (SFmode);
25008 e0 = gen_reg_rtx (SFmode);
25009 e1 = gen_reg_rtx (SFmode);
25010 y1 = gen_reg_rtx (SFmode);
25011 u0 = gen_reg_rtx (SFmode);
25012 v0 = gen_reg_rtx (SFmode);
25013 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25015 /* x0 = 1./d estimate */
25016 emit_insn (gen_rtx_SET (VOIDmode, x0,
25017 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25019 /* e0 = 1. - d * x0 */
25020 emit_insn (gen_rtx_SET (VOIDmode, e0,
25021 gen_rtx_MINUS (SFmode, one,
25022 gen_rtx_MULT (SFmode, d, x0))));
25023 /* e1 = e0 + e0 * e0 */
25024 emit_insn (gen_rtx_SET (VOIDmode, e1,
25025 gen_rtx_PLUS (SFmode,
25026 gen_rtx_MULT (SFmode, e0, e0), e0)));
25027 /* y1 = x0 + e1 * x0 */
25028 emit_insn (gen_rtx_SET (VOIDmode, y1,
25029 gen_rtx_PLUS (SFmode,
25030 gen_rtx_MULT (SFmode, e1, x0), x0)));
25032 emit_insn (gen_rtx_SET (VOIDmode, u0,
25033 gen_rtx_MULT (SFmode, n, y1)));
25034 /* v0 = n - d * u0 */
25035 emit_insn (gen_rtx_SET (VOIDmode, v0,
25036 gen_rtx_MINUS (SFmode, n,
25037 gen_rtx_MULT (SFmode, d, u0))));
25038 /* dst = u0 + v0 * y1 */
25039 emit_insn (gen_rtx_SET (VOIDmode, dst,
25040 gen_rtx_PLUS (SFmode,
25041 gen_rtx_MULT (SFmode, v0, y1), u0)));
25044 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25045 Assumes no trapping math and finite arguments. */
25048 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25050 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25052 x0 = gen_reg_rtx (DFmode);
25053 e0 = gen_reg_rtx (DFmode);
25054 e1 = gen_reg_rtx (DFmode);
25055 e2 = gen_reg_rtx (DFmode);
25056 y1 = gen_reg_rtx (DFmode);
25057 y2 = gen_reg_rtx (DFmode);
25058 y3 = gen_reg_rtx (DFmode);
25059 u0 = gen_reg_rtx (DFmode);
25060 v0 = gen_reg_rtx (DFmode);
25061 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25063 /* x0 = 1./d estimate */
25064 emit_insn (gen_rtx_SET (VOIDmode, x0,
25065 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25067 /* e0 = 1. - d * x0 */
25068 emit_insn (gen_rtx_SET (VOIDmode, e0,
25069 gen_rtx_MINUS (DFmode, one,
25070 gen_rtx_MULT (SFmode, d, x0))));
25071 /* y1 = x0 + e0 * x0 */
25072 emit_insn (gen_rtx_SET (VOIDmode, y1,
25073 gen_rtx_PLUS (DFmode,
25074 gen_rtx_MULT (DFmode, e0, x0), x0)));
25076 emit_insn (gen_rtx_SET (VOIDmode, e1,
25077 gen_rtx_MULT (DFmode, e0, e0)));
25078 /* y2 = y1 + e1 * y1 */
25079 emit_insn (gen_rtx_SET (VOIDmode, y2,
25080 gen_rtx_PLUS (DFmode,
25081 gen_rtx_MULT (DFmode, e1, y1), y1)));
25083 emit_insn (gen_rtx_SET (VOIDmode, e2,
25084 gen_rtx_MULT (DFmode, e1, e1)));
25085 /* y3 = y2 + e2 * y2 */
25086 emit_insn (gen_rtx_SET (VOIDmode, y3,
25087 gen_rtx_PLUS (DFmode,
25088 gen_rtx_MULT (DFmode, e2, y2), y2)));
25090 emit_insn (gen_rtx_SET (VOIDmode, u0,
25091 gen_rtx_MULT (DFmode, n, y3)));
25092 /* v0 = n - d * u0 */
25093 emit_insn (gen_rtx_SET (VOIDmode, v0,
25094 gen_rtx_MINUS (DFmode, n,
25095 gen_rtx_MULT (DFmode, d, u0))));
25096 /* dst = u0 + v0 * y3 */
25097 emit_insn (gen_rtx_SET (VOIDmode, dst,
25098 gen_rtx_PLUS (DFmode,
25099 gen_rtx_MULT (DFmode, v0, y3), u0)));
25103 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25104 Assumes no trapping math and finite arguments. */
25107 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25109 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25110 half, one, halfthree, c1, cond, label;
25112 x0 = gen_reg_rtx (SFmode);
25113 x1 = gen_reg_rtx (SFmode);
25114 x2 = gen_reg_rtx (SFmode);
25115 y1 = gen_reg_rtx (SFmode);
25116 u0 = gen_reg_rtx (SFmode);
25117 u1 = gen_reg_rtx (SFmode);
25118 u2 = gen_reg_rtx (SFmode);
25119 v0 = gen_reg_rtx (SFmode);
25120 v1 = gen_reg_rtx (SFmode);
25121 v2 = gen_reg_rtx (SFmode);
25122 t0 = gen_reg_rtx (SFmode);
25123 halfthree = gen_reg_rtx (SFmode);
25124 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25125 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25127 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25128 emit_insn (gen_rtx_SET (VOIDmode, t0,
25129 gen_rtx_MULT (SFmode, src, src)));
25131 emit_insn (gen_rtx_SET (VOIDmode, cond,
25132 gen_rtx_COMPARE (CCFPmode, t0, src)));
25133 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25134 emit_unlikely_jump (c1, label);
25136 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25137 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25139 /* halfthree = 1.5 = 1.0 + 0.5 */
25140 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25141 gen_rtx_PLUS (SFmode, one, half)));
25143 /* x0 = rsqrt estimate */
25144 emit_insn (gen_rtx_SET (VOIDmode, x0,
25145 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25148 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25149 emit_insn (gen_rtx_SET (VOIDmode, y1,
25150 gen_rtx_MINUS (SFmode,
25151 gen_rtx_MULT (SFmode, src, halfthree),
25154 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25155 emit_insn (gen_rtx_SET (VOIDmode, u0,
25156 gen_rtx_MULT (SFmode, x0, x0)));
25157 emit_insn (gen_rtx_SET (VOIDmode, v0,
25158 gen_rtx_MINUS (SFmode,
25160 gen_rtx_MULT (SFmode, y1, u0))));
25161 emit_insn (gen_rtx_SET (VOIDmode, x1,
25162 gen_rtx_MULT (SFmode, x0, v0)));
25164 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25165 emit_insn (gen_rtx_SET (VOIDmode, u1,
25166 gen_rtx_MULT (SFmode, x1, x1)));
25167 emit_insn (gen_rtx_SET (VOIDmode, v1,
25168 gen_rtx_MINUS (SFmode,
25170 gen_rtx_MULT (SFmode, y1, u1))));
25171 emit_insn (gen_rtx_SET (VOIDmode, x2,
25172 gen_rtx_MULT (SFmode, x1, v1)));
25174 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25175 emit_insn (gen_rtx_SET (VOIDmode, u2,
25176 gen_rtx_MULT (SFmode, x2, x2)));
25177 emit_insn (gen_rtx_SET (VOIDmode, v2,
25178 gen_rtx_MINUS (SFmode,
25180 gen_rtx_MULT (SFmode, y1, u2))));
25181 emit_insn (gen_rtx_SET (VOIDmode, dst,
25182 gen_rtx_MULT (SFmode, x2, v2)));
25184 emit_label (XEXP (label, 0));
25187 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25188 (Power7) targets. DST is the target, and SRC is the argument operand. */
25191 rs6000_emit_popcount (rtx dst, rtx src)
25193 enum machine_mode mode = GET_MODE (dst);
25196 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25197 if (TARGET_POPCNTD)
25199 if (mode == SImode)
25200 emit_insn (gen_popcntwsi2 (dst, src));
25202 emit_insn (gen_popcntddi2 (dst, src));
25206 tmp1 = gen_reg_rtx (mode);
25208 if (mode == SImode)
25210 emit_insn (gen_popcntbsi2 (tmp1, src));
25211 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25213 tmp2 = force_reg (SImode, tmp2);
25214 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25218 emit_insn (gen_popcntbdi2 (tmp1, src));
25219 tmp2 = expand_mult (DImode, tmp1,
25220 GEN_INT ((HOST_WIDE_INT)
25221 0x01010101 << 32 | 0x01010101),
25223 tmp2 = force_reg (DImode, tmp2);
25224 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25229 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25230 target, and SRC is the argument operand. */
25233 rs6000_emit_parity (rtx dst, rtx src)
25235 enum machine_mode mode = GET_MODE (dst);
25238 tmp = gen_reg_rtx (mode);
25239 if (mode == SImode)
25241 /* Is mult+shift >= shift+xor+shift+xor? */
25242 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25244 rtx tmp1, tmp2, tmp3, tmp4;
25246 tmp1 = gen_reg_rtx (SImode);
25247 emit_insn (gen_popcntbsi2 (tmp1, src));
25249 tmp2 = gen_reg_rtx (SImode);
25250 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25251 tmp3 = gen_reg_rtx (SImode);
25252 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25254 tmp4 = gen_reg_rtx (SImode);
25255 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25256 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25259 rs6000_emit_popcount (tmp, src);
25260 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25264 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25265 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25267 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25269 tmp1 = gen_reg_rtx (DImode);
25270 emit_insn (gen_popcntbdi2 (tmp1, src));
25272 tmp2 = gen_reg_rtx (DImode);
25273 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25274 tmp3 = gen_reg_rtx (DImode);
25275 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25277 tmp4 = gen_reg_rtx (DImode);
25278 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25279 tmp5 = gen_reg_rtx (DImode);
25280 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25282 tmp6 = gen_reg_rtx (DImode);
25283 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25284 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25287 rs6000_emit_popcount (tmp, src);
25288 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25292 /* Return an RTX representing where to find the function value of a
25293 function returning MODE. */
25295 rs6000_complex_function_value (enum machine_mode mode)
25297 unsigned int regno;
25299 enum machine_mode inner = GET_MODE_INNER (mode);
25300 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25302 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25303 regno = FP_ARG_RETURN;
25306 regno = GP_ARG_RETURN;
25308 /* 32-bit is OK since it'll go in r3/r4. */
25309 if (TARGET_32BIT && inner_bytes >= 4)
25310 return gen_rtx_REG (mode, regno);
25313 if (inner_bytes >= 8)
25314 return gen_rtx_REG (mode, regno);
25316 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25318 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25319 GEN_INT (inner_bytes));
25320 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25323 /* Target hook for TARGET_FUNCTION_VALUE.
25325 On the SPE, both FPs and vectors are returned in r3.
25327 On RS/6000 an integer value is in r3 and a floating-point value is in
25328 fp1, unless -msoft-float. */
25331 rs6000_function_value (const_tree valtype,
25332 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25333 bool outgoing ATTRIBUTE_UNUSED)
25335 enum machine_mode mode;
25336 unsigned int regno;
25338 /* Special handling for structs in darwin64. */
25339 if (rs6000_darwin64_abi
25340 && TYPE_MODE (valtype) == BLKmode
25341 && TREE_CODE (valtype) == RECORD_TYPE
25342 && int_size_in_bytes (valtype) > 0)
25344 CUMULATIVE_ARGS valcum;
25348 valcum.fregno = FP_ARG_MIN_REG;
25349 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25350 /* Do a trial code generation as if this were going to be passed as
25351 an argument; if any part goes in memory, we return NULL. */
25352 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25355 /* Otherwise fall through to standard ABI rules. */
25358 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25360 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25361 return gen_rtx_PARALLEL (DImode,
25363 gen_rtx_EXPR_LIST (VOIDmode,
25364 gen_rtx_REG (SImode, GP_ARG_RETURN),
25366 gen_rtx_EXPR_LIST (VOIDmode,
25367 gen_rtx_REG (SImode,
25368 GP_ARG_RETURN + 1),
25371 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25373 return gen_rtx_PARALLEL (DCmode,
25375 gen_rtx_EXPR_LIST (VOIDmode,
25376 gen_rtx_REG (SImode, GP_ARG_RETURN),
25378 gen_rtx_EXPR_LIST (VOIDmode,
25379 gen_rtx_REG (SImode,
25380 GP_ARG_RETURN + 1),
25382 gen_rtx_EXPR_LIST (VOIDmode,
25383 gen_rtx_REG (SImode,
25384 GP_ARG_RETURN + 2),
25386 gen_rtx_EXPR_LIST (VOIDmode,
25387 gen_rtx_REG (SImode,
25388 GP_ARG_RETURN + 3),
25392 mode = TYPE_MODE (valtype);
25393 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25394 || POINTER_TYPE_P (valtype))
25395 mode = TARGET_32BIT ? SImode : DImode;
25397 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25398 /* _Decimal128 must use an even/odd register pair. */
25399 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25400 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25401 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25402 regno = FP_ARG_RETURN;
25403 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25404 && targetm.calls.split_complex_arg)
25405 return rs6000_complex_function_value (mode);
25406 else if (TREE_CODE (valtype) == VECTOR_TYPE
25407 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25408 && ALTIVEC_VECTOR_MODE (mode))
25409 regno = ALTIVEC_ARG_RETURN;
25410 else if (TREE_CODE (valtype) == VECTOR_TYPE
25411 && TARGET_VSX && TARGET_ALTIVEC_ABI
25412 && VSX_VECTOR_MODE (mode))
25413 regno = ALTIVEC_ARG_RETURN;
25414 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25415 && (mode == DFmode || mode == DCmode
25416 || mode == TFmode || mode == TCmode))
25417 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25419 regno = GP_ARG_RETURN;
25421 return gen_rtx_REG (mode, regno);
25424 /* Define how to find the value returned by a library function
25425 assuming the value has mode MODE. */
25427 rs6000_libcall_value (enum machine_mode mode)
25429 unsigned int regno;
25431 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25433 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25434 return gen_rtx_PARALLEL (DImode,
25436 gen_rtx_EXPR_LIST (VOIDmode,
25437 gen_rtx_REG (SImode, GP_ARG_RETURN),
25439 gen_rtx_EXPR_LIST (VOIDmode,
25440 gen_rtx_REG (SImode,
25441 GP_ARG_RETURN + 1),
25445 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25446 /* _Decimal128 must use an even/odd register pair. */
25447 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25448 else if (SCALAR_FLOAT_MODE_P (mode)
25449 && TARGET_HARD_FLOAT && TARGET_FPRS
25450 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25451 regno = FP_ARG_RETURN;
25452 else if (ALTIVEC_VECTOR_MODE (mode)
25453 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25454 regno = ALTIVEC_ARG_RETURN;
25455 else if (VSX_VECTOR_MODE (mode)
25456 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25457 regno = ALTIVEC_ARG_RETURN;
25458 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25459 return rs6000_complex_function_value (mode);
25460 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25461 && (mode == DFmode || mode == DCmode
25462 || mode == TFmode || mode == TCmode))
25463 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25465 regno = GP_ARG_RETURN;
25467 return gen_rtx_REG (mode, regno);
25471 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25472 Frame pointer elimination is automatically handled.
25474 For the RS/6000, if frame pointer elimination is being done, we would like
25475 to convert ap into fp, not sp.
25477 We need r30 if -mminimal-toc was specified, and there are constant pool
25481 rs6000_can_eliminate (const int from, const int to)
25483 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25484 ? ! frame_pointer_needed
25485 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25486 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25490 /* Define the offset between two registers, FROM to be eliminated and its
25491 replacement TO, at the start of a routine. */
25493 rs6000_initial_elimination_offset (int from, int to)
25495 rs6000_stack_t *info = rs6000_stack_info ();
25496 HOST_WIDE_INT offset;
25498 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25499 offset = info->push_p ? 0 : -info->total_size;
25500 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25502 offset = info->push_p ? 0 : -info->total_size;
25503 if (FRAME_GROWS_DOWNWARD)
25504 offset += info->fixed_size + info->vars_size + info->parm_size;
25506 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25507 offset = FRAME_GROWS_DOWNWARD
25508 ? info->fixed_size + info->vars_size + info->parm_size
25510 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25511 offset = info->total_size;
25512 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25513 offset = info->push_p ? info->total_size : 0;
25514 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25517 gcc_unreachable ();
25523 rs6000_dwarf_register_span (rtx reg)
25527 unsigned regno = REGNO (reg);
25528 enum machine_mode mode = GET_MODE (reg);
25532 && (SPE_VECTOR_MODE (GET_MODE (reg))
25533 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25534 && mode != SFmode && mode != SDmode && mode != SCmode)))
25539 regno = REGNO (reg);
25541 /* The duality of the SPE register size wreaks all kinds of havoc.
25542 This is a way of distinguishing r0 in 32-bits from r0 in
25544 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25545 gcc_assert (words <= 4);
25546 for (i = 0; i < words; i++, regno++)
25548 if (BYTES_BIG_ENDIAN)
25550 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25551 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25555 parts[2 * i] = gen_rtx_REG (SImode, regno);
25556 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25560 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25563 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25566 rs6000_init_dwarf_reg_sizes_extra (tree address)
25571 enum machine_mode mode = TYPE_MODE (char_type_node);
25572 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25573 rtx mem = gen_rtx_MEM (BLKmode, addr);
25574 rtx value = gen_int_mode (4, mode);
25576 for (i = 1201; i < 1232; i++)
25578 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25579 HOST_WIDE_INT offset
25580 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25582 emit_move_insn (adjust_address (mem, mode, offset), value);
25587 /* Map internal gcc register numbers to DWARF2 register numbers. */
25590 rs6000_dbx_register_number (unsigned int regno)
25592 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25594 if (regno == MQ_REGNO)
25596 if (regno == LR_REGNO)
25598 if (regno == CTR_REGNO)
25600 if (CR_REGNO_P (regno))
25601 return regno - CR0_REGNO + 86;
25602 if (regno == XER_REGNO)
25604 if (ALTIVEC_REGNO_P (regno))
25605 return regno - FIRST_ALTIVEC_REGNO + 1124;
25606 if (regno == VRSAVE_REGNO)
25608 if (regno == VSCR_REGNO)
25610 if (regno == SPE_ACC_REGNO)
25612 if (regno == SPEFSCR_REGNO)
25614 /* SPE high reg number. We get these values of regno from
25615 rs6000_dwarf_register_span. */
25616 gcc_assert (regno >= 1200 && regno < 1232);
25620 /* target hook eh_return_filter_mode */
25621 static enum machine_mode
25622 rs6000_eh_return_filter_mode (void)
25624 return TARGET_32BIT ? SImode : word_mode;
25627 /* Target hook for scalar_mode_supported_p. */
25629 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25631 if (DECIMAL_FLOAT_MODE_P (mode))
25632 return default_decimal_float_supported_p ();
25634 return default_scalar_mode_supported_p (mode);
25637 /* Target hook for vector_mode_supported_p. */
25639 rs6000_vector_mode_supported_p (enum machine_mode mode)
25642 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25645 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25648 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25655 /* Target hook for invalid_arg_for_unprototyped_fn. */
25656 static const char *
25657 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25659 return (!rs6000_darwin64_abi
25661 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25662 && (funcdecl == NULL_TREE
25663 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25664 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25665 ? N_("AltiVec argument passed to unprototyped function")
25669 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25670 setup by using __stack_chk_fail_local hidden function instead of
25671 calling __stack_chk_fail directly. Otherwise it is better to call
25672 __stack_chk_fail directly. */
25675 rs6000_stack_protect_fail (void)
25677 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25678 ? default_hidden_stack_protect_fail ()
25679 : default_external_stack_protect_fail ();
25683 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25684 int num_operands ATTRIBUTE_UNUSED)
25686 if (rs6000_warn_cell_microcode)
25689 int insn_code_number = recog_memoized (insn);
25690 location_t location = locator_location (INSN_LOCATOR (insn));
25692 /* Punt on insns we cannot recognize. */
25693 if (insn_code_number < 0)
25696 temp = get_insn_template (insn_code_number, insn);
25698 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25699 warning_at (location, OPT_mwarn_cell_microcode,
25700 "emitting microcode insn %s\t[%s] #%d",
25701 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25702 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25703 warning_at (location, OPT_mwarn_cell_microcode,
25704 "emitting conditional microcode insn %s\t[%s] #%d",
25705 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25709 #include "gt-rs6000.h"