1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
257 traceback_default = 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC476 processors. */
516 struct processor_costs ppc476_cost = {
517 COSTS_N_INSNS (4), /* mulsi */
518 COSTS_N_INSNS (4), /* mulsi_const */
519 COSTS_N_INSNS (4), /* mulsi_const9 */
520 COSTS_N_INSNS (4), /* muldi */
521 COSTS_N_INSNS (11), /* divsi */
522 COSTS_N_INSNS (11), /* divdi */
523 COSTS_N_INSNS (6), /* fp */
524 COSTS_N_INSNS (6), /* dmul */
525 COSTS_N_INSNS (19), /* sdiv */
526 COSTS_N_INSNS (33), /* ddiv */
527 32, /* l1 cache line size */
533 /* Instruction costs on PPC601 processors. */
535 struct processor_costs ppc601_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (5), /* mulsi_const */
538 COSTS_N_INSNS (5), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (36), /* divsi */
541 COSTS_N_INSNS (36), /* divdi */
542 COSTS_N_INSNS (4), /* fp */
543 COSTS_N_INSNS (5), /* dmul */
544 COSTS_N_INSNS (17), /* sdiv */
545 COSTS_N_INSNS (31), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC603 processors. */
554 struct processor_costs ppc603_cost = {
555 COSTS_N_INSNS (5), /* mulsi */
556 COSTS_N_INSNS (3), /* mulsi_const */
557 COSTS_N_INSNS (2), /* mulsi_const9 */
558 COSTS_N_INSNS (5), /* muldi */
559 COSTS_N_INSNS (37), /* divsi */
560 COSTS_N_INSNS (37), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (4), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (33), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604 processors. */
573 struct processor_costs ppc604_cost = {
574 COSTS_N_INSNS (4), /* mulsi */
575 COSTS_N_INSNS (4), /* mulsi_const */
576 COSTS_N_INSNS (4), /* mulsi_const9 */
577 COSTS_N_INSNS (4), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC604e processors. */
592 struct processor_costs ppc604e_cost = {
593 COSTS_N_INSNS (2), /* mulsi */
594 COSTS_N_INSNS (2), /* mulsi_const */
595 COSTS_N_INSNS (2), /* mulsi_const9 */
596 COSTS_N_INSNS (2), /* muldi */
597 COSTS_N_INSNS (20), /* divsi */
598 COSTS_N_INSNS (20), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 32, /* cache line size */
609 /* Instruction costs on PPC620 processors. */
611 struct processor_costs ppc620_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (18), /* sdiv */
621 COSTS_N_INSNS (32), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on PPC630 processors. */
630 struct processor_costs ppc630_cost = {
631 COSTS_N_INSNS (5), /* mulsi */
632 COSTS_N_INSNS (4), /* mulsi_const */
633 COSTS_N_INSNS (3), /* mulsi_const9 */
634 COSTS_N_INSNS (7), /* muldi */
635 COSTS_N_INSNS (21), /* divsi */
636 COSTS_N_INSNS (37), /* divdi */
637 COSTS_N_INSNS (3), /* fp */
638 COSTS_N_INSNS (3), /* dmul */
639 COSTS_N_INSNS (17), /* sdiv */
640 COSTS_N_INSNS (21), /* ddiv */
641 128, /* cache line size */
647 /* Instruction costs on Cell processor. */
648 /* COSTS_N_INSNS (1) ~ one add. */
650 struct processor_costs ppccell_cost = {
651 COSTS_N_INSNS (9/2)+2, /* mulsi */
652 COSTS_N_INSNS (6/2), /* mulsi_const */
653 COSTS_N_INSNS (6/2), /* mulsi_const9 */
654 COSTS_N_INSNS (15/2)+2, /* muldi */
655 COSTS_N_INSNS (38/2), /* divsi */
656 COSTS_N_INSNS (70/2), /* divdi */
657 COSTS_N_INSNS (10/2), /* fp */
658 COSTS_N_INSNS (10/2), /* dmul */
659 COSTS_N_INSNS (74/2), /* sdiv */
660 COSTS_N_INSNS (74/2), /* ddiv */
661 128, /* cache line size */
667 /* Instruction costs on PPC750 and PPC7400 processors. */
669 struct processor_costs ppc750_cost = {
670 COSTS_N_INSNS (5), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (2), /* mulsi_const9 */
673 COSTS_N_INSNS (5), /* muldi */
674 COSTS_N_INSNS (17), /* divsi */
675 COSTS_N_INSNS (17), /* divdi */
676 COSTS_N_INSNS (3), /* fp */
677 COSTS_N_INSNS (3), /* dmul */
678 COSTS_N_INSNS (17), /* sdiv */
679 COSTS_N_INSNS (31), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC7450 processors. */
688 struct processor_costs ppc7450_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (3), /* mulsi_const */
691 COSTS_N_INSNS (3), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (23), /* divsi */
694 COSTS_N_INSNS (23), /* divdi */
695 COSTS_N_INSNS (5), /* fp */
696 COSTS_N_INSNS (5), /* dmul */
697 COSTS_N_INSNS (21), /* sdiv */
698 COSTS_N_INSNS (35), /* ddiv */
699 32, /* cache line size */
705 /* Instruction costs on PPC8540 processors. */
707 struct processor_costs ppc8540_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (4), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (29), /* sdiv */
717 COSTS_N_INSNS (29), /* ddiv */
718 32, /* cache line size */
721 1, /* prefetch streams /*/
724 /* Instruction costs on E300C2 and E300C3 cores. */
726 struct processor_costs ppce300c2c3_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (19), /* divsi */
732 COSTS_N_INSNS (19), /* divdi */
733 COSTS_N_INSNS (3), /* fp */
734 COSTS_N_INSNS (4), /* dmul */
735 COSTS_N_INSNS (18), /* sdiv */
736 COSTS_N_INSNS (33), /* ddiv */
740 1, /* prefetch streams /*/
743 /* Instruction costs on PPCE500MC processors. */
745 struct processor_costs ppce500mc_cost = {
746 COSTS_N_INSNS (4), /* mulsi */
747 COSTS_N_INSNS (4), /* mulsi_const */
748 COSTS_N_INSNS (4), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (14), /* divsi */
751 COSTS_N_INSNS (14), /* divdi */
752 COSTS_N_INSNS (8), /* fp */
753 COSTS_N_INSNS (10), /* dmul */
754 COSTS_N_INSNS (36), /* sdiv */
755 COSTS_N_INSNS (66), /* ddiv */
756 64, /* cache line size */
759 1, /* prefetch streams /*/
762 /* Instruction costs on PPCE500MC64 processors. */
764 struct processor_costs ppce500mc64_cost = {
765 COSTS_N_INSNS (4), /* mulsi */
766 COSTS_N_INSNS (4), /* mulsi_const */
767 COSTS_N_INSNS (4), /* mulsi_const9 */
768 COSTS_N_INSNS (4), /* muldi */
769 COSTS_N_INSNS (14), /* divsi */
770 COSTS_N_INSNS (14), /* divdi */
771 COSTS_N_INSNS (4), /* fp */
772 COSTS_N_INSNS (10), /* dmul */
773 COSTS_N_INSNS (36), /* sdiv */
774 COSTS_N_INSNS (66), /* ddiv */
775 64, /* cache line size */
778 1, /* prefetch streams /*/
781 /* Instruction costs on POWER4 and POWER5 processors. */
783 struct processor_costs power4_cost = {
784 COSTS_N_INSNS (3), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (4), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (17), /* sdiv */
793 COSTS_N_INSNS (17), /* ddiv */
794 128, /* cache line size */
797 8, /* prefetch streams /*/
800 /* Instruction costs on POWER6 processors. */
802 struct processor_costs power6_cost = {
803 COSTS_N_INSNS (8), /* mulsi */
804 COSTS_N_INSNS (8), /* mulsi_const */
805 COSTS_N_INSNS (8), /* mulsi_const9 */
806 COSTS_N_INSNS (8), /* muldi */
807 COSTS_N_INSNS (22), /* divsi */
808 COSTS_N_INSNS (28), /* divdi */
809 COSTS_N_INSNS (3), /* fp */
810 COSTS_N_INSNS (3), /* dmul */
811 COSTS_N_INSNS (13), /* sdiv */
812 COSTS_N_INSNS (16), /* ddiv */
813 128, /* cache line size */
816 16, /* prefetch streams */
819 /* Instruction costs on POWER7 processors. */
821 struct processor_costs power7_cost = {
822 COSTS_N_INSNS (2), /* mulsi */
823 COSTS_N_INSNS (2), /* mulsi_const */
824 COSTS_N_INSNS (2), /* mulsi_const9 */
825 COSTS_N_INSNS (2), /* muldi */
826 COSTS_N_INSNS (18), /* divsi */
827 COSTS_N_INSNS (34), /* divdi */
828 COSTS_N_INSNS (3), /* fp */
829 COSTS_N_INSNS (3), /* dmul */
830 COSTS_N_INSNS (13), /* sdiv */
831 COSTS_N_INSNS (16), /* ddiv */
832 128, /* cache line size */
835 12, /* prefetch streams */
838 /* Instruction costs on POWER A2 processors. */
840 struct processor_costs ppca2_cost = {
841 COSTS_N_INSNS (16), /* mulsi */
842 COSTS_N_INSNS (16), /* mulsi_const */
843 COSTS_N_INSNS (16), /* mulsi_const9 */
844 COSTS_N_INSNS (16), /* muldi */
845 COSTS_N_INSNS (22), /* divsi */
846 COSTS_N_INSNS (28), /* divdi */
847 COSTS_N_INSNS (3), /* fp */
848 COSTS_N_INSNS (3), /* dmul */
849 COSTS_N_INSNS (59), /* sdiv */
850 COSTS_N_INSNS (72), /* ddiv */
854 16, /* prefetch streams */
858 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
859 #undef RS6000_BUILTIN
860 #undef RS6000_BUILTIN_EQUATE
861 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
862 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
864 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
866 #include "rs6000-builtin.def"
869 #undef RS6000_BUILTIN
870 #undef RS6000_BUILTIN_EQUATE
873 static bool rs6000_function_ok_for_sibcall (tree, tree);
874 static const char *rs6000_invalid_within_doloop (const_rtx);
875 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
876 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
877 static rtx rs6000_generate_compare (rtx, enum machine_mode);
878 static void rs6000_emit_stack_tie (void);
879 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
880 static bool spe_func_has_64bit_regs_p (void);
881 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
883 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
884 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
885 static unsigned rs6000_hash_constant (rtx);
886 static unsigned toc_hash_function (const void *);
887 static int toc_hash_eq (const void *, const void *);
888 static bool reg_offset_addressing_ok_p (enum machine_mode);
889 static bool virtual_stack_registers_memory_p (rtx);
890 static bool constant_pool_expr_p (rtx);
891 static bool legitimate_small_data_p (enum machine_mode, rtx);
892 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
893 static struct machine_function * rs6000_init_machine_status (void);
894 static bool rs6000_assemble_integer (rtx, unsigned int, int);
895 static bool no_global_regs_above (int, bool);
896 #ifdef HAVE_GAS_HIDDEN
897 static void rs6000_assemble_visibility (tree, int);
899 static int rs6000_ra_ever_killed (void);
900 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
901 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
902 static bool rs6000_ms_bitfield_layout_p (const_tree);
903 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
904 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
905 static const char *rs6000_mangle_type (const_tree);
906 static void rs6000_set_default_type_attributes (tree);
907 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
908 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
909 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
910 enum machine_mode, bool, bool, bool);
911 static bool rs6000_reg_live_or_pic_offset_p (int);
912 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
913 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
914 static void rs6000_restore_saved_cr (rtx, int);
915 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
916 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
917 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
919 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
920 static bool rs6000_return_in_memory (const_tree, const_tree);
921 static rtx rs6000_function_value (const_tree, const_tree, bool);
922 static void rs6000_file_start (void);
924 static int rs6000_elf_reloc_rw_mask (void);
925 static void rs6000_elf_asm_out_constructor (rtx, int);
926 static void rs6000_elf_asm_out_destructor (rtx, int);
927 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
928 static void rs6000_elf_asm_init_sections (void);
929 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
930 unsigned HOST_WIDE_INT);
931 static void rs6000_elf_encode_section_info (tree, rtx, int)
934 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
935 static void rs6000_alloc_sdmode_stack_slot (void);
936 static void rs6000_instantiate_decls (void);
938 static void rs6000_xcoff_asm_output_anchor (rtx);
939 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
940 static void rs6000_xcoff_asm_init_sections (void);
941 static int rs6000_xcoff_reloc_rw_mask (void);
942 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
943 static section *rs6000_xcoff_select_section (tree, int,
944 unsigned HOST_WIDE_INT);
945 static void rs6000_xcoff_unique_section (tree, int);
946 static section *rs6000_xcoff_select_rtx_section
947 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
948 static const char * rs6000_xcoff_strip_name_encoding (const char *);
949 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
950 static void rs6000_xcoff_file_start (void);
951 static void rs6000_xcoff_file_end (void);
953 static int rs6000_variable_issue (FILE *, int, rtx, int);
954 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
955 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
956 static int rs6000_debug_address_cost (rtx, bool);
957 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
958 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
959 static void rs6000_sched_init (FILE *, int, int);
960 static bool is_microcoded_insn (rtx);
961 static bool is_nonpipeline_insn (rtx);
962 static bool is_cracked_insn (rtx);
963 static bool is_branch_slot_insn (rtx);
964 static bool is_load_insn (rtx);
965 static rtx get_store_dest (rtx pat);
966 static bool is_store_insn (rtx);
967 static bool set_to_load_agen (rtx,rtx);
968 static bool adjacent_mem_locations (rtx,rtx);
969 static int rs6000_adjust_priority (rtx, int);
970 static int rs6000_issue_rate (void);
971 static bool rs6000_is_costly_dependence (dep_t, int, int);
972 static rtx get_next_active_insn (rtx, rtx);
973 static bool insn_terminates_group_p (rtx , enum group_termination);
974 static bool insn_must_be_first_in_group (rtx);
975 static bool insn_must_be_last_in_group (rtx);
976 static bool is_costly_group (rtx *, rtx);
977 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
978 static int redefine_groups (FILE *, int, rtx, rtx);
979 static int pad_groups (FILE *, int, rtx, rtx);
980 static void rs6000_sched_finish (FILE *, int);
981 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
982 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
983 static int rs6000_use_sched_lookahead (void);
984 static int rs6000_use_sched_lookahead_guard (rtx);
985 static void * rs6000_alloc_sched_context (void);
986 static void rs6000_init_sched_context (void *, bool);
987 static void rs6000_set_sched_context (void *);
988 static void rs6000_free_sched_context (void *);
989 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
990 static tree rs6000_builtin_mask_for_load (void);
991 static tree rs6000_builtin_mul_widen_even (tree);
992 static tree rs6000_builtin_mul_widen_odd (tree);
993 static tree rs6000_builtin_conversion (unsigned int, tree);
994 static tree rs6000_builtin_vec_perm (tree, tree *);
995 static bool rs6000_builtin_support_vector_misalignment (enum
1000 static void def_builtin (int, const char *, tree, int);
1001 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1002 static void rs6000_init_builtins (void);
1003 static tree rs6000_builtin_decl (unsigned, bool);
1005 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1006 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1007 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1008 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1009 static void altivec_init_builtins (void);
1010 static unsigned builtin_hash_function (const void *);
1011 static int builtin_hash_eq (const void *, const void *);
1012 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1013 enum machine_mode, enum machine_mode,
1014 enum rs6000_builtins, const char *name);
1015 static void rs6000_common_init_builtins (void);
1016 static void rs6000_init_libfuncs (void);
1018 static void paired_init_builtins (void);
1019 static rtx paired_expand_builtin (tree, rtx, bool *);
1020 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1021 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1022 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1024 static void enable_mask_for_builtins (struct builtin_description *, int,
1025 enum rs6000_builtins,
1026 enum rs6000_builtins);
1027 static void spe_init_builtins (void);
1028 static rtx spe_expand_builtin (tree, rtx, bool *);
1029 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1030 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1031 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1032 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1033 static rs6000_stack_t *rs6000_stack_info (void);
1034 static void debug_stack_info (rs6000_stack_t *);
1036 static rtx altivec_expand_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1038 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1039 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1041 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1042 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1043 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1044 static rtx altivec_expand_vec_set_builtin (tree);
1045 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1046 static int get_element_number (tree, tree);
1047 static bool rs6000_handle_option (size_t, const char *, int);
1048 static void rs6000_parse_tls_size_option (void);
1049 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1050 static int first_altivec_reg_to_save (void);
1051 static unsigned int compute_vrsave_mask (void);
1052 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1053 static void is_altivec_return_reg (rtx, void *);
1054 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1055 int easy_vector_constant (rtx, enum machine_mode);
1056 static rtx rs6000_dwarf_register_span (rtx);
1057 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1058 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1059 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1060 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1061 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1062 static rtx rs6000_delegitimize_address (rtx);
1063 static rtx rs6000_tls_get_addr (void);
1064 static rtx rs6000_got_sym (void);
1065 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1066 static const char *rs6000_get_some_local_dynamic_name (void);
1067 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1068 static rtx rs6000_complex_function_value (enum machine_mode);
1069 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1070 enum machine_mode, tree);
1071 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1073 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1074 tree, HOST_WIDE_INT);
1075 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1078 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1079 const_tree, HOST_WIDE_INT,
1081 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1082 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1083 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1084 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1085 enum machine_mode, tree,
1087 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1089 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1091 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1093 static void macho_branch_islands (void);
1094 static int no_previous_def (tree function_name);
1095 static tree get_prev_label (tree function_name);
1096 static void rs6000_darwin_file_start (void);
1099 static tree rs6000_build_builtin_va_list (void);
1100 static void rs6000_va_start (tree, rtx);
1101 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1102 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1103 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1104 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1105 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1106 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1108 static tree rs6000_stack_protect_fail (void);
1110 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1113 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1116 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1118 = rs6000_legitimize_reload_address;
1120 static bool rs6000_mode_dependent_address (rtx);
1121 static bool rs6000_debug_mode_dependent_address (rtx);
1122 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1123 = rs6000_mode_dependent_address;
1125 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1126 enum machine_mode, rtx);
1127 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1130 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1131 enum machine_mode, rtx)
1132 = rs6000_secondary_reload_class;
1134 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1135 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1137 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1138 = rs6000_preferred_reload_class;
1140 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1143 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1147 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1149 = rs6000_secondary_memory_needed;
1151 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1154 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1158 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1161 = rs6000_cannot_change_mode_class;
1163 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1165 struct secondary_reload_info *);
1167 static const enum reg_class *rs6000_ira_cover_classes (void);
1169 const int INSN_NOT_AVAILABLE = -1;
1170 static enum machine_mode rs6000_eh_return_filter_mode (void);
1171 static bool rs6000_can_eliminate (const int, const int);
1172 static void rs6000_trampoline_init (rtx, tree, rtx);
1174 /* Hash table stuff for keeping track of TOC entries. */
1176 struct GTY(()) toc_hash_struct
1178 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1179 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1181 enum machine_mode key_mode;
1185 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1187 /* Hash table to keep track of the argument types for builtin functions. */
1189 struct GTY(()) builtin_hash_struct
1192 enum machine_mode mode[4]; /* return value + 3 arguments. */
1193 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1196 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1198 /* Default register names. */
1199 char rs6000_reg_names[][8] =
1201 "0", "1", "2", "3", "4", "5", "6", "7",
1202 "8", "9", "10", "11", "12", "13", "14", "15",
1203 "16", "17", "18", "19", "20", "21", "22", "23",
1204 "24", "25", "26", "27", "28", "29", "30", "31",
1205 "0", "1", "2", "3", "4", "5", "6", "7",
1206 "8", "9", "10", "11", "12", "13", "14", "15",
1207 "16", "17", "18", "19", "20", "21", "22", "23",
1208 "24", "25", "26", "27", "28", "29", "30", "31",
1209 "mq", "lr", "ctr","ap",
1210 "0", "1", "2", "3", "4", "5", "6", "7",
1212 /* AltiVec registers. */
1213 "0", "1", "2", "3", "4", "5", "6", "7",
1214 "8", "9", "10", "11", "12", "13", "14", "15",
1215 "16", "17", "18", "19", "20", "21", "22", "23",
1216 "24", "25", "26", "27", "28", "29", "30", "31",
1218 /* SPE registers. */
1219 "spe_acc", "spefscr",
1220 /* Soft frame pointer. */
1224 #ifdef TARGET_REGNAMES
1225 static const char alt_reg_names[][8] =
1227 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1228 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1229 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1230 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1231 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1232 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1233 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1234 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1235 "mq", "lr", "ctr", "ap",
1236 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1238 /* AltiVec registers. */
1239 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1240 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1241 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1242 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1244 /* SPE registers. */
1245 "spe_acc", "spefscr",
1246 /* Soft frame pointer. */
1251 /* Table of valid machine attributes. */
1253 static const struct attribute_spec rs6000_attribute_table[] =
1255 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1256 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1257 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1258 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1259 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1260 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1261 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1262 SUBTARGET_ATTRIBUTE_TABLE,
1264 { NULL, 0, 0, false, false, false, NULL }
1267 #ifndef MASK_STRICT_ALIGN
1268 #define MASK_STRICT_ALIGN 0
1270 #ifndef TARGET_PROFILE_KERNEL
1271 #define TARGET_PROFILE_KERNEL 0
1274 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1275 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1277 /* Initialize the GCC target structure. */
1278 #undef TARGET_ATTRIBUTE_TABLE
1279 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1280 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1281 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1283 #undef TARGET_ASM_ALIGNED_DI_OP
1284 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1286 /* Default unaligned ops are only provided for ELF. Find the ops needed
1287 for non-ELF systems. */
1288 #ifndef OBJECT_FORMAT_ELF
1290 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1292 #undef TARGET_ASM_UNALIGNED_HI_OP
1293 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1294 #undef TARGET_ASM_UNALIGNED_SI_OP
1295 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1296 #undef TARGET_ASM_UNALIGNED_DI_OP
1297 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1300 #undef TARGET_ASM_UNALIGNED_HI_OP
1301 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1302 #undef TARGET_ASM_UNALIGNED_SI_OP
1303 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1304 #undef TARGET_ASM_UNALIGNED_DI_OP
1305 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1306 #undef TARGET_ASM_ALIGNED_DI_OP
1307 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1311 /* This hook deals with fixups for relocatable code and DI-mode objects
1313 #undef TARGET_ASM_INTEGER
1314 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1316 #ifdef HAVE_GAS_HIDDEN
1317 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1318 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1321 #undef TARGET_HAVE_TLS
1322 #define TARGET_HAVE_TLS HAVE_AS_TLS
1324 #undef TARGET_CANNOT_FORCE_CONST_MEM
1325 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1327 #undef TARGET_DELEGITIMIZE_ADDRESS
1328 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1330 #undef TARGET_ASM_FUNCTION_PROLOGUE
1331 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1332 #undef TARGET_ASM_FUNCTION_EPILOGUE
1333 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1335 #undef TARGET_LEGITIMIZE_ADDRESS
1336 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1338 #undef TARGET_SCHED_VARIABLE_ISSUE
1339 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1341 #undef TARGET_SCHED_ISSUE_RATE
1342 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1343 #undef TARGET_SCHED_ADJUST_COST
1344 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1345 #undef TARGET_SCHED_ADJUST_PRIORITY
1346 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1347 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1348 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1349 #undef TARGET_SCHED_INIT
1350 #define TARGET_SCHED_INIT rs6000_sched_init
1351 #undef TARGET_SCHED_FINISH
1352 #define TARGET_SCHED_FINISH rs6000_sched_finish
1353 #undef TARGET_SCHED_REORDER
1354 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1355 #undef TARGET_SCHED_REORDER2
1356 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1358 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1359 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1361 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1362 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1364 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1365 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1366 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1367 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1368 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1369 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1370 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1371 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1373 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1374 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1375 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1376 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1377 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1378 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1379 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1380 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1381 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1382 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1383 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1384 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1385 rs6000_builtin_support_vector_misalignment
1386 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1387 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1389 #undef TARGET_INIT_BUILTINS
1390 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1391 #undef TARGET_BUILTIN_DECL
1392 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1394 #undef TARGET_EXPAND_BUILTIN
1395 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1397 #undef TARGET_MANGLE_TYPE
1398 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1400 #undef TARGET_INIT_LIBFUNCS
1401 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1404 #undef TARGET_BINDS_LOCAL_P
1405 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1408 #undef TARGET_MS_BITFIELD_LAYOUT_P
1409 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1411 #undef TARGET_ASM_OUTPUT_MI_THUNK
1412 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1414 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1415 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1417 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1418 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1420 #undef TARGET_INVALID_WITHIN_DOLOOP
1421 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1423 #undef TARGET_RTX_COSTS
1424 #define TARGET_RTX_COSTS rs6000_rtx_costs
1425 #undef TARGET_ADDRESS_COST
1426 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1428 #undef TARGET_DWARF_REGISTER_SPAN
1429 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1431 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1432 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1434 /* On rs6000, function arguments are promoted, as are function return
1436 #undef TARGET_PROMOTE_FUNCTION_MODE
1437 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1439 #undef TARGET_RETURN_IN_MEMORY
1440 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1442 #undef TARGET_SETUP_INCOMING_VARARGS
1443 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1445 /* Always strict argument naming on rs6000. */
1446 #undef TARGET_STRICT_ARGUMENT_NAMING
1447 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1448 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1449 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1450 #undef TARGET_SPLIT_COMPLEX_ARG
1451 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1452 #undef TARGET_MUST_PASS_IN_STACK
1453 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1454 #undef TARGET_PASS_BY_REFERENCE
1455 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1456 #undef TARGET_ARG_PARTIAL_BYTES
1457 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1459 #undef TARGET_BUILD_BUILTIN_VA_LIST
1460 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1462 #undef TARGET_EXPAND_BUILTIN_VA_START
1463 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1465 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1466 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1468 #undef TARGET_EH_RETURN_FILTER_MODE
1469 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1471 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1472 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1474 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1475 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1477 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1478 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1480 #undef TARGET_HANDLE_OPTION
1481 #define TARGET_HANDLE_OPTION rs6000_handle_option
1483 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1484 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1485 rs6000_builtin_vectorized_function
1487 #undef TARGET_DEFAULT_TARGET_FLAGS
1488 #define TARGET_DEFAULT_TARGET_FLAGS \
1491 #undef TARGET_STACK_PROTECT_FAIL
1492 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1494 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1495 The PowerPC architecture requires only weak consistency among
1496 processors--that is, memory accesses between processors need not be
1497 sequentially consistent and memory accesses among processors can occur
1498 in any order. The ability to order memory accesses weakly provides
1499 opportunities for more efficient use of the system bus. Unless a
1500 dependency exists, the 604e allows read operations to precede store
1502 #undef TARGET_RELAXED_ORDERING
1503 #define TARGET_RELAXED_ORDERING true
1506 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1507 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1510 /* Use a 32-bit anchor range. This leads to sequences like:
1512 addis tmp,anchor,high
1515 where tmp itself acts as an anchor, and can be shared between
1516 accesses to the same 64k page. */
1517 #undef TARGET_MIN_ANCHOR_OFFSET
1518 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1519 #undef TARGET_MAX_ANCHOR_OFFSET
1520 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1521 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1522 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1524 #undef TARGET_BUILTIN_RECIPROCAL
1525 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1527 #undef TARGET_EXPAND_TO_RTL_HOOK
1528 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1530 #undef TARGET_INSTANTIATE_DECLS
1531 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1533 #undef TARGET_SECONDARY_RELOAD
1534 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1536 #undef TARGET_IRA_COVER_CLASSES
1537 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1539 #undef TARGET_LEGITIMATE_ADDRESS_P
1540 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1542 #undef TARGET_CAN_ELIMINATE
1543 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1545 #undef TARGET_TRAMPOLINE_INIT
1546 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1548 #undef TARGET_FUNCTION_VALUE
1549 #define TARGET_FUNCTION_VALUE rs6000_function_value
1551 struct gcc_target targetm = TARGET_INITIALIZER;
1553 /* Return number of consecutive hard regs needed starting at reg REGNO
1554 to hold something of mode MODE.
1555 This is ordinarily the length in words of a value of mode MODE
1556 but can be less for certain modes in special long registers.
1558 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1559 scalar instructions. The upper 32 bits are only available to the
1562 POWER and PowerPC GPRs hold 32 bits worth;
1563 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1566 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1568 unsigned HOST_WIDE_INT reg_size;
1570 if (FP_REGNO_P (regno))
1571 reg_size = (VECTOR_MEM_VSX_P (mode)
1572 ? UNITS_PER_VSX_WORD
1573 : UNITS_PER_FP_WORD);
1575 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1576 reg_size = UNITS_PER_SPE_WORD;
1578 else if (ALTIVEC_REGNO_P (regno))
1579 reg_size = UNITS_PER_ALTIVEC_WORD;
1581 /* The value returned for SCmode in the E500 double case is 2 for
1582 ABI compatibility; storing an SCmode value in a single register
1583 would require function_arg and rs6000_spe_function_arg to handle
1584 SCmode so as to pass the value correctly in a pair of
1586 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1587 && !DECIMAL_FLOAT_MODE_P (mode))
1588 reg_size = UNITS_PER_FP_WORD;
1591 reg_size = UNITS_PER_WORD;
1593 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1596 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1599 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1601 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1603 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1604 implementations. Don't allow an item to be split between a FP register
1605 and an Altivec register. */
1606 if (VECTOR_MEM_VSX_P (mode))
1608 if (FP_REGNO_P (regno))
1609 return FP_REGNO_P (last_regno);
1611 if (ALTIVEC_REGNO_P (regno))
1612 return ALTIVEC_REGNO_P (last_regno);
1615 /* The GPRs can hold any mode, but values bigger than one register
1616 cannot go past R31. */
1617 if (INT_REGNO_P (regno))
1618 return INT_REGNO_P (last_regno);
1620 /* The float registers (except for VSX vector modes) can only hold floating
1621 modes and DImode. This excludes the 32-bit decimal float mode for
1623 if (FP_REGNO_P (regno))
1625 if (SCALAR_FLOAT_MODE_P (mode)
1626 && (mode != TDmode || (regno % 2) == 0)
1627 && FP_REGNO_P (last_regno))
1630 if (GET_MODE_CLASS (mode) == MODE_INT
1631 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1634 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1635 && PAIRED_VECTOR_MODE (mode))
1641 /* The CR register can only hold CC modes. */
1642 if (CR_REGNO_P (regno))
1643 return GET_MODE_CLASS (mode) == MODE_CC;
1645 if (XER_REGNO_P (regno))
1646 return mode == PSImode;
1648 /* AltiVec only in AldyVec registers. */
1649 if (ALTIVEC_REGNO_P (regno))
1650 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1652 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1653 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1656 /* We cannot put TImode anywhere except general register and it must be able
1657 to fit within the register set. In the future, allow TImode in the
1658 Altivec or VSX registers. */
1660 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1663 /* Print interesting facts about registers. */
1665 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1669 for (r = first_regno; r <= last_regno; ++r)
1671 const char *comma = "";
1674 if (first_regno == last_regno)
1675 fprintf (stderr, "%s:\t", reg_name);
1677 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1680 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1681 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1685 fprintf (stderr, ",\n\t");
1690 if (rs6000_hard_regno_nregs[m][r] > 1)
1691 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1692 rs6000_hard_regno_nregs[m][r]);
1694 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1699 if (call_used_regs[r])
1703 fprintf (stderr, ",\n\t");
1708 len += fprintf (stderr, "%s%s", comma, "call-used");
1716 fprintf (stderr, ",\n\t");
1721 len += fprintf (stderr, "%s%s", comma, "fixed");
1727 fprintf (stderr, ",\n\t");
1731 fprintf (stderr, "%sregno = %d\n", comma, r);
1735 /* Print various interesting information with -mdebug=reg. */
1737 rs6000_debug_reg_global (void)
1739 const char *nl = (const char *)0;
1741 char costly_num[20];
1743 const char *costly_str;
1744 const char *nop_str;
1746 /* Map enum rs6000_vector to string. */
1747 static const char *rs6000_debug_vector_unit[] = {
1756 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1757 LAST_VIRTUAL_REGISTER);
1758 rs6000_debug_reg_print (0, 31, "gr");
1759 rs6000_debug_reg_print (32, 63, "fp");
1760 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1763 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1764 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1765 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1766 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1767 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1768 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1769 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1770 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1771 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1775 "d reg_class = %s\n"
1776 "f reg_class = %s\n"
1777 "v reg_class = %s\n"
1778 "wa reg_class = %s\n"
1779 "wd reg_class = %s\n"
1780 "wf reg_class = %s\n"
1781 "ws reg_class = %s\n\n",
1782 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1783 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1784 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1790 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1791 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1794 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1796 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1797 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1803 switch (rs6000_sched_costly_dep)
1805 case max_dep_latency:
1806 costly_str = "max_dep_latency";
1810 costly_str = "no_dep_costly";
1813 case all_deps_costly:
1814 costly_str = "all_deps_costly";
1817 case true_store_to_load_dep_costly:
1818 costly_str = "true_store_to_load_dep_costly";
1821 case store_to_load_dep_costly:
1822 costly_str = "store_to_load_dep_costly";
1826 costly_str = costly_num;
1827 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1831 switch (rs6000_sched_insert_nops)
1833 case sched_finish_regroup_exact:
1834 nop_str = "sched_finish_regroup_exact";
1837 case sched_finish_pad_groups:
1838 nop_str = "sched_finish_pad_groups";
1841 case sched_finish_none:
1842 nop_str = "sched_finish_none";
1847 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1852 "always_hint = %s\n"
1853 "align_branch_targets = %s\n"
1854 "sched_restricted_insns_priority = %d\n"
1855 "sched_costly_dep = %s\n"
1856 "sched_insert_nops = %s\n\n",
1857 rs6000_always_hint ? "true" : "false",
1858 rs6000_align_branch_targets ? "true" : "false",
1859 (int)rs6000_sched_restricted_insns_priority,
1860 costly_str, nop_str);
1863 /* Initialize the various global tables that are based on register size. */
1865 rs6000_init_hard_regno_mode_ok (void)
1871 /* Precalculate REGNO_REG_CLASS. */
1872 rs6000_regno_regclass[0] = GENERAL_REGS;
1873 for (r = 1; r < 32; ++r)
1874 rs6000_regno_regclass[r] = BASE_REGS;
1876 for (r = 32; r < 64; ++r)
1877 rs6000_regno_regclass[r] = FLOAT_REGS;
1879 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1880 rs6000_regno_regclass[r] = NO_REGS;
1882 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1883 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1885 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1886 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1887 rs6000_regno_regclass[r] = CR_REGS;
1889 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1890 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1891 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1892 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1893 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1894 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1895 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1896 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1897 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1898 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1900 /* Precalculate vector information, this must be set up before the
1901 rs6000_hard_regno_nregs_internal below. */
1902 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1904 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1905 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1906 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1909 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1910 rs6000_constraints[c] = NO_REGS;
1912 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1913 believes it can use native alignment or still uses 128-bit alignment. */
1914 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1925 /* V2DF mode, VSX only. */
1928 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1929 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1930 rs6000_vector_align[V2DFmode] = align64;
1933 /* V4SF mode, either VSX or Altivec. */
1936 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1937 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1938 rs6000_vector_align[V4SFmode] = align32;
1940 else if (TARGET_ALTIVEC)
1942 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1943 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1944 rs6000_vector_align[V4SFmode] = align32;
1947 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1951 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1952 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1953 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1954 rs6000_vector_align[V4SImode] = align32;
1955 rs6000_vector_align[V8HImode] = align32;
1956 rs6000_vector_align[V16QImode] = align32;
1960 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1961 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1962 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1966 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1967 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1968 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1972 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1973 Altivec doesn't have 64-bit support. */
1976 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1977 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1978 rs6000_vector_align[V2DImode] = align64;
1981 /* DFmode, see if we want to use the VSX unit. */
1982 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1984 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1985 rs6000_vector_mem[DFmode]
1986 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1987 rs6000_vector_align[DFmode] = align64;
1990 /* TODO add SPE and paired floating point vector support. */
1992 /* Register class constaints for the constraints that depend on compile
1994 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1995 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1997 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1998 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2002 /* At present, we just use VSX_REGS, but we have different constraints
2003 based on the use, in case we want to fine tune the default register
2004 class used. wa = any VSX register, wf = register class to use for
2005 V4SF, wd = register class to use for V2DF, and ws = register classs to
2006 use for DF scalars. */
2007 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2008 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2009 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2010 if (TARGET_VSX_SCALAR_DOUBLE)
2011 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2015 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2017 /* Set up the reload helper functions. */
2018 if (TARGET_VSX || TARGET_ALTIVEC)
2022 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2023 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2024 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2025 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2026 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2027 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2028 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2029 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2030 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2031 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2032 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2033 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2037 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2038 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2039 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2040 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2041 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2042 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2043 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2044 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2045 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2046 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2047 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2048 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2052 /* Precalculate HARD_REGNO_NREGS. */
2053 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2054 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2055 rs6000_hard_regno_nregs[m][r]
2056 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2058 /* Precalculate HARD_REGNO_MODE_OK. */
2059 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2060 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2061 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2062 rs6000_hard_regno_mode_ok_p[m][r] = true;
2064 /* Precalculate CLASS_MAX_NREGS sizes. */
2065 for (c = 0; c < LIM_REG_CLASSES; ++c)
2069 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2070 reg_size = UNITS_PER_VSX_WORD;
2072 else if (c == ALTIVEC_REGS)
2073 reg_size = UNITS_PER_ALTIVEC_WORD;
2075 else if (c == FLOAT_REGS)
2076 reg_size = UNITS_PER_FP_WORD;
2079 reg_size = UNITS_PER_WORD;
2081 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2082 rs6000_class_max_nregs[m][c]
2083 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2086 if (TARGET_E500_DOUBLE)
2087 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2089 if (TARGET_DEBUG_REG)
2090 rs6000_debug_reg_global ();
2094 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2097 darwin_rs6000_override_options (void)
2099 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2101 rs6000_altivec_abi = 1;
2102 TARGET_ALTIVEC_VRSAVE = 1;
2103 if (DEFAULT_ABI == ABI_DARWIN)
2105 if (MACHO_DYNAMIC_NO_PIC_P)
2108 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2111 else if (flag_pic == 1)
2116 if (TARGET_64BIT && ! TARGET_POWERPC64)
2118 target_flags |= MASK_POWERPC64;
2119 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2123 rs6000_default_long_calls = 1;
2124 target_flags |= MASK_SOFT_FLOAT;
2127 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2129 if (!flag_mkernel && !flag_apple_kext
2131 && ! (target_flags_explicit & MASK_ALTIVEC))
2132 target_flags |= MASK_ALTIVEC;
2134 /* Unless the user (not the configurer) has explicitly overridden
2135 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2136 G4 unless targetting the kernel. */
2139 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2140 && ! (target_flags_explicit & MASK_ALTIVEC)
2141 && ! rs6000_select[1].string)
2143 target_flags |= MASK_ALTIVEC;
2148 /* If not otherwise specified by a target, make 'long double' equivalent to
2151 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2152 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2155 /* Override command line options. Mostly we process the processor
2156 type and sometimes adjust other TARGET_ options. */
2159 rs6000_override_options (const char *default_cpu)
2162 struct rs6000_cpu_select *ptr;
2165 /* Simplifications for entries below. */
2168 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2169 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2172 /* This table occasionally claims that a processor does not support
2173 a particular feature even though it does, but the feature is slower
2174 than the alternative. Thus, it shouldn't be relied on as a
2175 complete description of the processor's support.
2177 Please keep this list in order, and don't forget to update the
2178 documentation in invoke.texi when adding a new processor or
2182 const char *const name; /* Canonical processor name. */
2183 const enum processor_type processor; /* Processor type enum value. */
2184 const int target_enable; /* Target flags to enable. */
2185 } const processor_target_table[]
2186 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2187 {"403", PROCESSOR_PPC403,
2188 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2189 {"405", PROCESSOR_PPC405,
2190 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2191 {"405fp", PROCESSOR_PPC405,
2192 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2193 {"440", PROCESSOR_PPC440,
2194 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2195 {"440fp", PROCESSOR_PPC440,
2196 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2197 {"464", PROCESSOR_PPC440,
2198 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2199 {"464fp", PROCESSOR_PPC440,
2200 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2201 {"476", PROCESSOR_PPC476,
2202 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2203 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2204 {"476fp", PROCESSOR_PPC476,
2205 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2206 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2207 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2208 {"601", PROCESSOR_PPC601,
2209 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2210 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2211 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2212 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2213 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2215 {"620", PROCESSOR_PPC620,
2216 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2217 {"630", PROCESSOR_PPC630,
2218 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2219 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2220 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2221 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2222 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2223 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2224 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2225 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2226 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2228 /* 8548 has a dummy entry for now. */
2229 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2231 {"a2", PROCESSOR_PPCA2,
2232 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2233 | MASK_CMPB | MASK_NO_UPDATE },
2234 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2235 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2236 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2238 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2239 | MASK_PPC_GFXOPT | MASK_ISEL},
2240 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2241 {"970", PROCESSOR_POWER4,
2242 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2243 {"cell", PROCESSOR_CELL,
2244 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2245 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2246 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2247 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2248 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2249 {"G5", PROCESSOR_POWER4,
2250 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2251 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2252 {"power2", PROCESSOR_POWER,
2253 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2254 {"power3", PROCESSOR_PPC630,
2255 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2256 {"power4", PROCESSOR_POWER4,
2257 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2259 {"power5", PROCESSOR_POWER5,
2260 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2261 | MASK_MFCRF | MASK_POPCNTB},
2262 {"power5+", PROCESSOR_POWER5,
2263 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2264 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2265 {"power6", PROCESSOR_POWER6,
2266 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2267 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2268 {"power6x", PROCESSOR_POWER6,
2269 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2270 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2272 {"power7", PROCESSOR_POWER7,
2273 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2274 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2275 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2276 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2277 {"powerpc64", PROCESSOR_POWERPC64,
2278 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2279 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2280 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2281 {"rios2", PROCESSOR_RIOS2,
2282 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2283 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2285 {"rs64", PROCESSOR_RS64A,
2286 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2289 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2291 /* Some OSs don't support saving the high part of 64-bit registers on
2292 context switch. Other OSs don't support saving Altivec registers.
2293 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2294 settings; if the user wants either, the user must explicitly specify
2295 them and we won't interfere with the user's specification. */
2298 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2299 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2300 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2301 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2302 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2303 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2306 /* Numerous experiment shows that IRA based loop pressure
2307 calculation works better for RTL loop invariant motion on targets
2308 with enough (>= 32) registers. It is an expensive optimization.
2309 So it is on only for peak performance. */
2311 flag_ira_loop_pressure = 1;
2313 /* Set the pointer size. */
2316 rs6000_pmode = (int)DImode;
2317 rs6000_pointer_size = 64;
2321 rs6000_pmode = (int)SImode;
2322 rs6000_pointer_size = 32;
2325 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2326 #ifdef OS_MISSING_POWERPC64
2327 if (OS_MISSING_POWERPC64)
2328 set_masks &= ~MASK_POWERPC64;
2330 #ifdef OS_MISSING_ALTIVEC
2331 if (OS_MISSING_ALTIVEC)
2332 set_masks &= ~MASK_ALTIVEC;
2335 /* Don't override by the processor default if given explicitly. */
2336 set_masks &= ~target_flags_explicit;
2338 /* Identify the processor type. */
2339 rs6000_select[0].string = default_cpu;
2340 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2342 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2344 ptr = &rs6000_select[i];
2345 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2347 for (j = 0; j < ptt_size; j++)
2348 if (! strcmp (ptr->string, processor_target_table[j].name))
2350 if (ptr->set_tune_p)
2351 rs6000_cpu = processor_target_table[j].processor;
2353 if (ptr->set_arch_p)
2355 target_flags &= ~set_masks;
2356 target_flags |= (processor_target_table[j].target_enable
2363 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2367 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2368 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2371 error ("AltiVec not supported in this target");
2373 error ("Spe not supported in this target");
2376 /* Disable Cell microcode if we are optimizing for the Cell
2377 and not optimizing for size. */
2378 if (rs6000_gen_cell_microcode == -1)
2379 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2382 /* If we are optimizing big endian systems for space and it's OK to
2383 use instructions that would be microcoded on the Cell, use the
2384 load/store multiple and string instructions. */
2385 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2386 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2388 /* Don't allow -mmultiple or -mstring on little endian systems
2389 unless the cpu is a 750, because the hardware doesn't support the
2390 instructions used in little endian mode, and causes an alignment
2391 trap. The 750 does not cause an alignment trap (except when the
2392 target is unaligned). */
2394 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2396 if (TARGET_MULTIPLE)
2398 target_flags &= ~MASK_MULTIPLE;
2399 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2400 warning (0, "-mmultiple is not supported on little endian systems");
2405 target_flags &= ~MASK_STRING;
2406 if ((target_flags_explicit & MASK_STRING) != 0)
2407 warning (0, "-mstring is not supported on little endian systems");
2411 /* Add some warnings for VSX. */
2414 const char *msg = NULL;
2415 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2416 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2418 if (target_flags_explicit & MASK_VSX)
2419 msg = N_("-mvsx requires hardware floating point");
2421 target_flags &= ~ MASK_VSX;
2423 else if (TARGET_PAIRED_FLOAT)
2424 msg = N_("-mvsx and -mpaired are incompatible");
2425 /* The hardware will allow VSX and little endian, but until we make sure
2426 things like vector select, etc. work don't allow VSX on little endian
2427 systems at this point. */
2428 else if (!BYTES_BIG_ENDIAN)
2429 msg = N_("-mvsx used with little endian code");
2430 else if (TARGET_AVOID_XFORM > 0)
2431 msg = N_("-mvsx needs indexed addressing");
2432 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2434 if (target_flags_explicit & MASK_VSX)
2435 msg = N_("-mvsx and -mno-altivec are incompatible");
2437 msg = N_("-mno-altivec disables vsx");
2443 target_flags &= ~ MASK_VSX;
2445 else if (TARGET_VSX && !TARGET_ALTIVEC)
2446 target_flags |= MASK_ALTIVEC;
2449 /* Set debug flags */
2450 if (rs6000_debug_name)
2452 if (! strcmp (rs6000_debug_name, "all"))
2453 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2454 = rs6000_debug_addr = rs6000_debug_cost = 1;
2455 else if (! strcmp (rs6000_debug_name, "stack"))
2456 rs6000_debug_stack = 1;
2457 else if (! strcmp (rs6000_debug_name, "arg"))
2458 rs6000_debug_arg = 1;
2459 else if (! strcmp (rs6000_debug_name, "reg"))
2460 rs6000_debug_reg = 1;
2461 else if (! strcmp (rs6000_debug_name, "addr"))
2462 rs6000_debug_addr = 1;
2463 else if (! strcmp (rs6000_debug_name, "cost"))
2464 rs6000_debug_cost = 1;
2466 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2468 /* If the appropriate debug option is enabled, replace the target hooks
2469 with debug versions that call the real version and then prints
2470 debugging information. */
2471 if (TARGET_DEBUG_COST)
2473 targetm.rtx_costs = rs6000_debug_rtx_costs;
2474 targetm.address_cost = rs6000_debug_address_cost;
2475 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2478 if (TARGET_DEBUG_ADDR)
2480 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2481 targetm.legitimize_address = rs6000_debug_legitimize_address;
2482 rs6000_secondary_reload_class_ptr
2483 = rs6000_debug_secondary_reload_class;
2484 rs6000_secondary_memory_needed_ptr
2485 = rs6000_debug_secondary_memory_needed;
2486 rs6000_cannot_change_mode_class_ptr
2487 = rs6000_debug_cannot_change_mode_class;
2488 rs6000_preferred_reload_class_ptr
2489 = rs6000_debug_preferred_reload_class;
2490 rs6000_legitimize_reload_address_ptr
2491 = rs6000_debug_legitimize_reload_address;
2492 rs6000_mode_dependent_address_ptr
2493 = rs6000_debug_mode_dependent_address;
2497 if (rs6000_traceback_name)
2499 if (! strncmp (rs6000_traceback_name, "full", 4))
2500 rs6000_traceback = traceback_full;
2501 else if (! strncmp (rs6000_traceback_name, "part", 4))
2502 rs6000_traceback = traceback_part;
2503 else if (! strncmp (rs6000_traceback_name, "no", 2))
2504 rs6000_traceback = traceback_none;
2506 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2507 rs6000_traceback_name);
2510 if (!rs6000_explicit_options.long_double)
2511 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2513 #ifndef POWERPC_LINUX
2514 if (!rs6000_explicit_options.ieee)
2515 rs6000_ieeequad = 1;
2518 /* Enable Altivec ABI for AIX -maltivec. */
2519 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2520 rs6000_altivec_abi = 1;
2522 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2523 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2524 be explicitly overridden in either case. */
2527 if (!rs6000_explicit_options.altivec_abi
2528 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2529 rs6000_altivec_abi = 1;
2531 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2532 if (!rs6000_explicit_options.vrsave)
2533 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2536 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2537 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2539 rs6000_darwin64_abi = 1;
2541 darwin_one_byte_bool = 1;
2543 /* Default to natural alignment, for better performance. */
2544 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2547 /* Place FP constants in the constant pool instead of TOC
2548 if section anchors enabled. */
2549 if (flag_section_anchors)
2550 TARGET_NO_FP_IN_TOC = 1;
2552 /* Handle -mtls-size option. */
2553 rs6000_parse_tls_size_option ();
2555 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2556 SUBTARGET_OVERRIDE_OPTIONS;
2558 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2559 SUBSUBTARGET_OVERRIDE_OPTIONS;
2561 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2562 SUB3TARGET_OVERRIDE_OPTIONS;
2565 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2566 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2568 /* The e500 and e500mc do not have string instructions, and we set
2569 MASK_STRING above when optimizing for size. */
2570 if ((target_flags & MASK_STRING) != 0)
2571 target_flags = target_flags & ~MASK_STRING;
2573 else if (rs6000_select[1].string != NULL)
2575 /* For the powerpc-eabispe configuration, we set all these by
2576 default, so let's unset them if we manually set another
2577 CPU that is not the E500. */
2578 if (!rs6000_explicit_options.spe_abi)
2580 if (!rs6000_explicit_options.spe)
2582 if (!rs6000_explicit_options.float_gprs)
2583 rs6000_float_gprs = 0;
2584 if (!(target_flags_explicit & MASK_ISEL))
2585 target_flags &= ~MASK_ISEL;
2588 /* Detect invalid option combinations with E500. */
2591 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2592 && rs6000_cpu != PROCESSOR_POWER5
2593 && rs6000_cpu != PROCESSOR_POWER6
2594 && rs6000_cpu != PROCESSOR_POWER7
2595 && rs6000_cpu != PROCESSOR_PPCA2
2596 && rs6000_cpu != PROCESSOR_CELL);
2597 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2598 || rs6000_cpu == PROCESSOR_POWER5
2599 || rs6000_cpu == PROCESSOR_POWER7);
2600 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2601 || rs6000_cpu == PROCESSOR_POWER5
2602 || rs6000_cpu == PROCESSOR_POWER6
2603 || rs6000_cpu == PROCESSOR_POWER7
2604 || rs6000_cpu == PROCESSOR_PPCE500MC
2605 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2607 /* Allow debug switches to override the above settings. */
2608 if (TARGET_ALWAYS_HINT > 0)
2609 rs6000_always_hint = TARGET_ALWAYS_HINT;
2611 if (TARGET_SCHED_GROUPS > 0)
2612 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2614 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2615 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2617 rs6000_sched_restricted_insns_priority
2618 = (rs6000_sched_groups ? 1 : 0);
2620 /* Handle -msched-costly-dep option. */
2621 rs6000_sched_costly_dep
2622 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2624 if (rs6000_sched_costly_dep_str)
2626 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2627 rs6000_sched_costly_dep = no_dep_costly;
2628 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2629 rs6000_sched_costly_dep = all_deps_costly;
2630 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2631 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2632 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2633 rs6000_sched_costly_dep = store_to_load_dep_costly;
2635 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2636 atoi (rs6000_sched_costly_dep_str));
2639 /* Handle -minsert-sched-nops option. */
2640 rs6000_sched_insert_nops
2641 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2643 if (rs6000_sched_insert_nops_str)
2645 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2646 rs6000_sched_insert_nops = sched_finish_none;
2647 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2648 rs6000_sched_insert_nops = sched_finish_pad_groups;
2649 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2650 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2652 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2653 atoi (rs6000_sched_insert_nops_str));
2656 #ifdef TARGET_REGNAMES
2657 /* If the user desires alternate register names, copy in the
2658 alternate names now. */
2659 if (TARGET_REGNAMES)
2660 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2663 /* Set aix_struct_return last, after the ABI is determined.
2664 If -maix-struct-return or -msvr4-struct-return was explicitly
2665 used, don't override with the ABI default. */
2666 if (!rs6000_explicit_options.aix_struct_ret)
2667 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2669 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2670 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2673 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2675 /* We can only guarantee the availability of DI pseudo-ops when
2676 assembling for 64-bit targets. */
2679 targetm.asm_out.aligned_op.di = NULL;
2680 targetm.asm_out.unaligned_op.di = NULL;
2683 /* Set branch target alignment, if not optimizing for size. */
2686 /* Cell wants to be aligned 8byte for dual issue. */
2687 if (rs6000_cpu == PROCESSOR_CELL)
2689 if (align_functions <= 0)
2690 align_functions = 8;
2691 if (align_jumps <= 0)
2693 if (align_loops <= 0)
2696 if (rs6000_align_branch_targets)
2698 if (align_functions <= 0)
2699 align_functions = 16;
2700 if (align_jumps <= 0)
2702 if (align_loops <= 0)
2705 if (align_jumps_max_skip <= 0)
2706 align_jumps_max_skip = 15;
2707 if (align_loops_max_skip <= 0)
2708 align_loops_max_skip = 15;
2711 /* Arrange to save and restore machine status around nested functions. */
2712 init_machine_status = rs6000_init_machine_status;
2714 /* We should always be splitting complex arguments, but we can't break
2715 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2716 if (DEFAULT_ABI != ABI_AIX)
2717 targetm.calls.split_complex_arg = NULL;
2719 /* Initialize rs6000_cost with the appropriate target costs. */
2721 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2725 case PROCESSOR_RIOS1:
2726 rs6000_cost = &rios1_cost;
2729 case PROCESSOR_RIOS2:
2730 rs6000_cost = &rios2_cost;
2733 case PROCESSOR_RS64A:
2734 rs6000_cost = &rs64a_cost;
2737 case PROCESSOR_MPCCORE:
2738 rs6000_cost = &mpccore_cost;
2741 case PROCESSOR_PPC403:
2742 rs6000_cost = &ppc403_cost;
2745 case PROCESSOR_PPC405:
2746 rs6000_cost = &ppc405_cost;
2749 case PROCESSOR_PPC440:
2750 rs6000_cost = &ppc440_cost;
2753 case PROCESSOR_PPC476:
2754 rs6000_cost = &ppc476_cost;
2757 case PROCESSOR_PPC601:
2758 rs6000_cost = &ppc601_cost;
2761 case PROCESSOR_PPC603:
2762 rs6000_cost = &ppc603_cost;
2765 case PROCESSOR_PPC604:
2766 rs6000_cost = &ppc604_cost;
2769 case PROCESSOR_PPC604e:
2770 rs6000_cost = &ppc604e_cost;
2773 case PROCESSOR_PPC620:
2774 rs6000_cost = &ppc620_cost;
2777 case PROCESSOR_PPC630:
2778 rs6000_cost = &ppc630_cost;
2781 case PROCESSOR_CELL:
2782 rs6000_cost = &ppccell_cost;
2785 case PROCESSOR_PPC750:
2786 case PROCESSOR_PPC7400:
2787 rs6000_cost = &ppc750_cost;
2790 case PROCESSOR_PPC7450:
2791 rs6000_cost = &ppc7450_cost;
2794 case PROCESSOR_PPC8540:
2795 rs6000_cost = &ppc8540_cost;
2798 case PROCESSOR_PPCE300C2:
2799 case PROCESSOR_PPCE300C3:
2800 rs6000_cost = &ppce300c2c3_cost;
2803 case PROCESSOR_PPCE500MC:
2804 rs6000_cost = &ppce500mc_cost;
2807 case PROCESSOR_PPCE500MC64:
2808 rs6000_cost = &ppce500mc64_cost;
2811 case PROCESSOR_POWER4:
2812 case PROCESSOR_POWER5:
2813 rs6000_cost = &power4_cost;
2816 case PROCESSOR_POWER6:
2817 rs6000_cost = &power6_cost;
2820 case PROCESSOR_POWER7:
2821 rs6000_cost = &power7_cost;
2824 case PROCESSOR_PPCA2:
2825 rs6000_cost = &ppca2_cost;
2832 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2833 set_param_value ("simultaneous-prefetches",
2834 rs6000_cost->simultaneous_prefetches);
2835 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2836 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2837 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2838 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2839 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2840 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2842 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2843 can be optimized to ap = __builtin_next_arg (0). */
2844 if (DEFAULT_ABI != ABI_V4)
2845 targetm.expand_builtin_va_start = NULL;
2847 /* Set up single/double float flags.
2848 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2849 then set both flags. */
2850 if (TARGET_HARD_FLOAT && TARGET_FPRS
2851 && rs6000_single_float == 0 && rs6000_double_float == 0)
2852 rs6000_single_float = rs6000_double_float = 1;
2854 /* Reset single and double FP flags if target is E500. */
2857 rs6000_single_float = rs6000_double_float = 0;
2858 if (TARGET_E500_SINGLE)
2859 rs6000_single_float = 1;
2860 if (TARGET_E500_DOUBLE)
2861 rs6000_single_float = rs6000_double_float = 1;
2864 /* If not explicitly specified via option, decide whether to generate indexed
2865 load/store instructions. */
2866 if (TARGET_AVOID_XFORM == -1)
2867 /* Avoid indexed addressing when targeting Power6 in order to avoid
2868 the DERAT mispredict penalty. */
2869 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2871 rs6000_init_hard_regno_mode_ok ();
2874 /* Implement targetm.vectorize.builtin_mask_for_load. */
2876 rs6000_builtin_mask_for_load (void)
2878 if (TARGET_ALTIVEC || TARGET_VSX)
2879 return altivec_builtin_mask_for_load;
2884 /* Implement targetm.vectorize.builtin_conversion.
2885 Returns a decl of a function that implements conversion of an integer vector
2886 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2887 side of the conversion.
2888 Return NULL_TREE if it is not available. */
2890 rs6000_builtin_conversion (unsigned int tcode, tree type)
2892 enum tree_code code = (enum tree_code) tcode;
2896 case FIX_TRUNC_EXPR:
2897 switch (TYPE_MODE (type))
2900 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2903 return TYPE_UNSIGNED (type)
2904 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2905 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2908 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2911 return TYPE_UNSIGNED (type)
2912 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2913 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2920 switch (TYPE_MODE (type))
2923 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2926 return TYPE_UNSIGNED (type)
2927 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2928 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2931 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2934 return TYPE_UNSIGNED (type)
2935 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2936 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2947 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2949 rs6000_builtin_mul_widen_even (tree type)
2951 if (!TARGET_ALTIVEC)
2954 switch (TYPE_MODE (type))
2957 return TYPE_UNSIGNED (type)
2958 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2959 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2962 return TYPE_UNSIGNED (type)
2963 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2964 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2970 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2972 rs6000_builtin_mul_widen_odd (tree type)
2974 if (!TARGET_ALTIVEC)
2977 switch (TYPE_MODE (type))
2980 return TYPE_UNSIGNED (type)
2981 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2982 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2985 return TYPE_UNSIGNED (type)
2986 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2987 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2994 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2995 after applying N number of iterations. This routine does not determine
2996 how may iterations are required to reach desired alignment. */
2999 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3006 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3009 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3019 /* Assuming that all other types are naturally aligned. CHECKME! */
3024 /* Return true if the vector misalignment factor is supported by the
3027 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3034 /* Return if movmisalign pattern is not supported for this mode. */
3035 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3039 if (misalignment == -1)
3041 /* misalignment factor is unknown at compile time but we know
3042 it's word aligned. */
3043 if (rs6000_vector_alignment_reachable (type, is_packed))
3047 /* VSX supports word-aligned vector. */
3048 if (misalignment % 4 == 0)
3054 /* Implement targetm.vectorize.builtin_vec_perm. */
3056 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3058 tree inner_type = TREE_TYPE (type);
3059 bool uns_p = TYPE_UNSIGNED (inner_type);
3062 *mask_element_type = unsigned_char_type_node;
3064 switch (TYPE_MODE (type))
3068 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3069 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3074 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3075 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3080 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3081 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3085 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3089 if (!TARGET_ALLOW_DF_PERMUTE)
3092 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3096 if (!TARGET_ALLOW_DF_PERMUTE)
3100 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3101 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3112 /* Handle generic options of the form -mfoo=yes/no.
3113 NAME is the option name.
3114 VALUE is the option value.
3115 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3116 whether the option value is 'yes' or 'no' respectively. */
3118 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3122 else if (!strcmp (value, "yes"))
3124 else if (!strcmp (value, "no"))
3127 error ("unknown -m%s= option specified: '%s'", name, value);
3130 /* Validate and record the size specified with the -mtls-size option. */
3133 rs6000_parse_tls_size_option (void)
3135 if (rs6000_tls_size_string == 0)
3137 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3138 rs6000_tls_size = 16;
3139 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3140 rs6000_tls_size = 32;
3141 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3142 rs6000_tls_size = 64;
3144 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3148 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3150 if (DEFAULT_ABI == ABI_DARWIN)
3151 /* The Darwin libraries never set errno, so we might as well
3152 avoid calling them when that's the only reason we would. */
3153 flag_errno_math = 0;
3155 /* Double growth factor to counter reduced min jump length. */
3156 set_param_value ("max-grow-copy-bb-insns", 16);
3158 /* Enable section anchors by default.
3159 Skip section anchors for Objective C and Objective C++
3160 until front-ends fixed. */
3161 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3162 flag_section_anchors = 2;
3165 static enum fpu_type_t
3166 rs6000_parse_fpu_option (const char *option)
3168 if (!strcmp("none", option)) return FPU_NONE;
3169 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3170 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3171 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3172 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3173 error("unknown value %s for -mfpu", option);
3177 /* Returns a function decl for a vectorized version of the builtin function
3178 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3179 if it is not available. */
3182 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3185 enum machine_mode in_mode, out_mode;
3188 if (TREE_CODE (type_out) != VECTOR_TYPE
3189 || TREE_CODE (type_in) != VECTOR_TYPE
3190 || !TARGET_VECTORIZE_BUILTINS)
3193 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3194 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3195 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3196 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3200 case BUILT_IN_COPYSIGN:
3201 if (VECTOR_UNIT_VSX_P (V2DFmode)
3202 && out_mode == DFmode && out_n == 2
3203 && in_mode == DFmode && in_n == 2)
3204 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3206 case BUILT_IN_COPYSIGNF:
3207 if (out_mode != SFmode || out_n != 4
3208 || in_mode != SFmode || in_n != 4)
3210 if (VECTOR_UNIT_VSX_P (V4SFmode))
3211 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3212 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3213 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3216 if (VECTOR_UNIT_VSX_P (V2DFmode)
3217 && out_mode == DFmode && out_n == 2
3218 && in_mode == DFmode && in_n == 2)
3219 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3221 case BUILT_IN_SQRTF:
3222 if (VECTOR_UNIT_VSX_P (V4SFmode)
3223 && out_mode == SFmode && out_n == 4
3224 && in_mode == SFmode && in_n == 4)
3225 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3228 if (VECTOR_UNIT_VSX_P (V2DFmode)
3229 && out_mode == DFmode && out_n == 2
3230 && in_mode == DFmode && in_n == 2)
3231 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3233 case BUILT_IN_CEILF:
3234 if (out_mode != SFmode || out_n != 4
3235 || in_mode != SFmode || in_n != 4)
3237 if (VECTOR_UNIT_VSX_P (V4SFmode))
3238 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3239 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3240 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3242 case BUILT_IN_FLOOR:
3243 if (VECTOR_UNIT_VSX_P (V2DFmode)
3244 && out_mode == DFmode && out_n == 2
3245 && in_mode == DFmode && in_n == 2)
3246 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3248 case BUILT_IN_FLOORF:
3249 if (out_mode != SFmode || out_n != 4
3250 || in_mode != SFmode || in_n != 4)
3252 if (VECTOR_UNIT_VSX_P (V4SFmode))
3253 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3254 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3255 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3257 case BUILT_IN_TRUNC:
3258 if (VECTOR_UNIT_VSX_P (V2DFmode)
3259 && out_mode == DFmode && out_n == 2
3260 && in_mode == DFmode && in_n == 2)
3261 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3263 case BUILT_IN_TRUNCF:
3264 if (out_mode != SFmode || out_n != 4
3265 || in_mode != SFmode || in_n != 4)
3267 if (VECTOR_UNIT_VSX_P (V4SFmode))
3268 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3269 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3270 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3272 case BUILT_IN_NEARBYINT:
3273 if (VECTOR_UNIT_VSX_P (V2DFmode)
3274 && flag_unsafe_math_optimizations
3275 && out_mode == DFmode && out_n == 2
3276 && in_mode == DFmode && in_n == 2)
3277 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3279 case BUILT_IN_NEARBYINTF:
3280 if (VECTOR_UNIT_VSX_P (V4SFmode)
3281 && flag_unsafe_math_optimizations
3282 && out_mode == SFmode && out_n == 4
3283 && in_mode == SFmode && in_n == 4)
3284 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3287 if (VECTOR_UNIT_VSX_P (V2DFmode)
3288 && !flag_trapping_math
3289 && out_mode == DFmode && out_n == 2
3290 && in_mode == DFmode && in_n == 2)
3291 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3293 case BUILT_IN_RINTF:
3294 if (VECTOR_UNIT_VSX_P (V4SFmode)
3295 && !flag_trapping_math
3296 && out_mode == SFmode && out_n == 4
3297 && in_mode == SFmode && in_n == 4)
3298 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3307 /* Implement TARGET_HANDLE_OPTION. */
3310 rs6000_handle_option (size_t code, const char *arg, int value)
3312 enum fpu_type_t fpu_type = FPU_NONE;
3318 target_flags &= ~(MASK_POWER | MASK_POWER2
3319 | MASK_MULTIPLE | MASK_STRING);
3320 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3321 | MASK_MULTIPLE | MASK_STRING);
3323 case OPT_mno_powerpc:
3324 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3325 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3326 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3327 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3330 target_flags &= ~MASK_MINIMAL_TOC;
3331 TARGET_NO_FP_IN_TOC = 0;
3332 TARGET_NO_SUM_IN_TOC = 0;
3333 target_flags_explicit |= MASK_MINIMAL_TOC;
3334 #ifdef TARGET_USES_SYSV4_OPT
3335 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3336 just the same as -mminimal-toc. */
3337 target_flags |= MASK_MINIMAL_TOC;
3338 target_flags_explicit |= MASK_MINIMAL_TOC;
3342 #ifdef TARGET_USES_SYSV4_OPT
3344 /* Make -mtoc behave like -mminimal-toc. */
3345 target_flags |= MASK_MINIMAL_TOC;
3346 target_flags_explicit |= MASK_MINIMAL_TOC;
3350 #ifdef TARGET_USES_AIX64_OPT
3355 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3356 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3357 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3360 #ifdef TARGET_USES_AIX64_OPT
3365 target_flags &= ~MASK_POWERPC64;
3366 target_flags_explicit |= MASK_POWERPC64;
3369 case OPT_minsert_sched_nops_:
3370 rs6000_sched_insert_nops_str = arg;
3373 case OPT_mminimal_toc:
3376 TARGET_NO_FP_IN_TOC = 0;
3377 TARGET_NO_SUM_IN_TOC = 0;
3384 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3385 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3392 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3393 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3397 case OPT_mpowerpc_gpopt:
3398 case OPT_mpowerpc_gfxopt:
3401 target_flags |= MASK_POWERPC;
3402 target_flags_explicit |= MASK_POWERPC;
3406 case OPT_maix_struct_return:
3407 case OPT_msvr4_struct_return:
3408 rs6000_explicit_options.aix_struct_ret = true;
3412 rs6000_explicit_options.vrsave = true;
3413 TARGET_ALTIVEC_VRSAVE = value;
3417 rs6000_explicit_options.vrsave = true;
3418 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3422 target_flags_explicit |= MASK_ISEL;
3424 rs6000_parse_yes_no_option ("isel", arg, &isel);
3426 target_flags |= MASK_ISEL;
3428 target_flags &= ~MASK_ISEL;
3432 rs6000_explicit_options.spe = true;
3437 rs6000_explicit_options.spe = true;
3438 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3442 rs6000_debug_name = arg;
3445 #ifdef TARGET_USES_SYSV4_OPT
3447 rs6000_abi_name = arg;
3451 rs6000_sdata_name = arg;
3454 case OPT_mtls_size_:
3455 rs6000_tls_size_string = arg;
3458 case OPT_mrelocatable:
3461 target_flags |= MASK_MINIMAL_TOC;
3462 target_flags_explicit |= MASK_MINIMAL_TOC;
3463 TARGET_NO_FP_IN_TOC = 1;
3467 case OPT_mrelocatable_lib:
3470 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3471 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3472 TARGET_NO_FP_IN_TOC = 1;
3476 target_flags &= ~MASK_RELOCATABLE;
3477 target_flags_explicit |= MASK_RELOCATABLE;
3483 if (!strcmp (arg, "altivec"))
3485 rs6000_explicit_options.altivec_abi = true;
3486 rs6000_altivec_abi = 1;
3488 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3491 else if (! strcmp (arg, "no-altivec"))
3493 rs6000_explicit_options.altivec_abi = true;
3494 rs6000_altivec_abi = 0;
3496 else if (! strcmp (arg, "spe"))
3498 rs6000_explicit_options.spe_abi = true;
3500 rs6000_altivec_abi = 0;
3501 if (!TARGET_SPE_ABI)
3502 error ("not configured for ABI: '%s'", arg);
3504 else if (! strcmp (arg, "no-spe"))
3506 rs6000_explicit_options.spe_abi = true;
3510 /* These are here for testing during development only, do not
3511 document in the manual please. */
3512 else if (! strcmp (arg, "d64"))
3514 rs6000_darwin64_abi = 1;
3515 warning (0, "Using darwin64 ABI");
3517 else if (! strcmp (arg, "d32"))
3519 rs6000_darwin64_abi = 0;
3520 warning (0, "Using old darwin ABI");
3523 else if (! strcmp (arg, "ibmlongdouble"))
3525 rs6000_explicit_options.ieee = true;
3526 rs6000_ieeequad = 0;
3527 warning (0, "Using IBM extended precision long double");
3529 else if (! strcmp (arg, "ieeelongdouble"))
3531 rs6000_explicit_options.ieee = true;
3532 rs6000_ieeequad = 1;
3533 warning (0, "Using IEEE extended precision long double");
3538 error ("unknown ABI specified: '%s'", arg);
3544 rs6000_select[1].string = arg;
3548 rs6000_select[2].string = arg;
3551 case OPT_mtraceback_:
3552 rs6000_traceback_name = arg;
3555 case OPT_mfloat_gprs_:
3556 rs6000_explicit_options.float_gprs = true;
3557 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3558 rs6000_float_gprs = 1;
3559 else if (! strcmp (arg, "double"))
3560 rs6000_float_gprs = 2;
3561 else if (! strcmp (arg, "no"))
3562 rs6000_float_gprs = 0;
3565 error ("invalid option for -mfloat-gprs: '%s'", arg);
3570 case OPT_mlong_double_:
3571 rs6000_explicit_options.long_double = true;
3572 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3573 if (value != 64 && value != 128)
3575 error ("Unknown switch -mlong-double-%s", arg);
3576 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3580 rs6000_long_double_type_size = value;
3583 case OPT_msched_costly_dep_:
3584 rs6000_sched_costly_dep_str = arg;
3588 rs6000_explicit_options.alignment = true;
3589 if (! strcmp (arg, "power"))
3591 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3592 some C library functions, so warn about it. The flag may be
3593 useful for performance studies from time to time though, so
3594 don't disable it entirely. */
3595 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3596 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3597 " it is incompatible with the installed C and C++ libraries");
3598 rs6000_alignment_flags = MASK_ALIGN_POWER;
3600 else if (! strcmp (arg, "natural"))
3601 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3604 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3609 case OPT_msingle_float:
3610 if (!TARGET_SINGLE_FPU)
3611 warning (0, "-msingle-float option equivalent to -mhard-float");
3612 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3613 rs6000_double_float = 0;
3614 target_flags &= ~MASK_SOFT_FLOAT;
3615 target_flags_explicit |= MASK_SOFT_FLOAT;
3618 case OPT_mdouble_float:
3619 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3620 rs6000_single_float = 1;
3621 target_flags &= ~MASK_SOFT_FLOAT;
3622 target_flags_explicit |= MASK_SOFT_FLOAT;
3625 case OPT_msimple_fpu:
3626 if (!TARGET_SINGLE_FPU)
3627 warning (0, "-msimple-fpu option ignored");
3630 case OPT_mhard_float:
3631 /* -mhard_float implies -msingle-float and -mdouble-float. */
3632 rs6000_single_float = rs6000_double_float = 1;
3635 case OPT_msoft_float:
3636 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3637 rs6000_single_float = rs6000_double_float = 0;
3641 fpu_type = rs6000_parse_fpu_option(arg);
3642 if (fpu_type != FPU_NONE)
3643 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3645 target_flags &= ~MASK_SOFT_FLOAT;
3646 target_flags_explicit |= MASK_SOFT_FLOAT;
3647 rs6000_xilinx_fpu = 1;
3648 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3649 rs6000_single_float = 1;
3650 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3651 rs6000_single_float = rs6000_double_float = 1;
3652 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3653 rs6000_simple_fpu = 1;
3657 /* -mfpu=none is equivalent to -msoft-float */
3658 target_flags |= MASK_SOFT_FLOAT;
3659 target_flags_explicit |= MASK_SOFT_FLOAT;
3660 rs6000_single_float = rs6000_double_float = 0;
3667 /* Do anything needed at the start of the asm file. */
3670 rs6000_file_start (void)
3674 const char *start = buffer;
3675 struct rs6000_cpu_select *ptr;
3676 const char *default_cpu = TARGET_CPU_DEFAULT;
3677 FILE *file = asm_out_file;
3679 default_file_start ();
3681 #ifdef TARGET_BI_ARCH
3682 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3686 if (flag_verbose_asm)
3688 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3689 rs6000_select[0].string = default_cpu;
3691 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3693 ptr = &rs6000_select[i];
3694 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3696 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3701 if (PPC405_ERRATUM77)
3703 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3707 #ifdef USING_ELFOS_H
3708 switch (rs6000_sdata)
3710 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3711 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3712 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3713 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3716 if (rs6000_sdata && g_switch_value)
3718 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3728 #ifdef HAVE_AS_GNU_ATTRIBUTE
3729 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3731 fprintf (file, "\t.gnu_attribute 4, %d\n",
3732 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3733 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3735 fprintf (file, "\t.gnu_attribute 8, %d\n",
3736 (TARGET_ALTIVEC_ABI ? 2
3737 : TARGET_SPE_ABI ? 3
3739 fprintf (file, "\t.gnu_attribute 12, %d\n",
3740 aix_struct_return ? 2 : 1);
3745 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3747 switch_to_section (toc_section);
3748 switch_to_section (text_section);
3753 /* Return nonzero if this function is known to have a null epilogue. */
3756 direct_return (void)
3758 if (reload_completed)
3760 rs6000_stack_t *info = rs6000_stack_info ();
3762 if (info->first_gp_reg_save == 32
3763 && info->first_fp_reg_save == 64
3764 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3765 && ! info->lr_save_p
3766 && ! info->cr_save_p
3767 && info->vrsave_mask == 0
3775 /* Return the number of instructions it takes to form a constant in an
3776 integer register. */
3779 num_insns_constant_wide (HOST_WIDE_INT value)
3781 /* signed constant loadable with {cal|addi} */
3782 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3785 /* constant loadable with {cau|addis} */
3786 else if ((value & 0xffff) == 0
3787 && (value >> 31 == -1 || value >> 31 == 0))
3790 #if HOST_BITS_PER_WIDE_INT == 64
3791 else if (TARGET_POWERPC64)
3793 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3794 HOST_WIDE_INT high = value >> 31;
3796 if (high == 0 || high == -1)
3802 return num_insns_constant_wide (high) + 1;
3804 return num_insns_constant_wide (low) + 1;
3806 return (num_insns_constant_wide (high)
3807 + num_insns_constant_wide (low) + 1);
3816 num_insns_constant (rtx op, enum machine_mode mode)
3818 HOST_WIDE_INT low, high;
3820 switch (GET_CODE (op))
3823 #if HOST_BITS_PER_WIDE_INT == 64
3824 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3825 && mask64_operand (op, mode))
3829 return num_insns_constant_wide (INTVAL (op));
3832 if (mode == SFmode || mode == SDmode)
3837 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3838 if (DECIMAL_FLOAT_MODE_P (mode))
3839 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3841 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3842 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3845 if (mode == VOIDmode || mode == DImode)
3847 high = CONST_DOUBLE_HIGH (op);
3848 low = CONST_DOUBLE_LOW (op);
3855 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3856 if (DECIMAL_FLOAT_MODE_P (mode))
3857 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3859 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3860 high = l[WORDS_BIG_ENDIAN == 0];
3861 low = l[WORDS_BIG_ENDIAN != 0];
3865 return (num_insns_constant_wide (low)
3866 + num_insns_constant_wide (high));
3869 if ((high == 0 && low >= 0)
3870 || (high == -1 && low < 0))
3871 return num_insns_constant_wide (low);
3873 else if (mask64_operand (op, mode))
3877 return num_insns_constant_wide (high) + 1;
3880 return (num_insns_constant_wide (high)
3881 + num_insns_constant_wide (low) + 1);
3889 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3890 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3891 corresponding element of the vector, but for V4SFmode and V2SFmode,
3892 the corresponding "float" is interpreted as an SImode integer. */
3895 const_vector_elt_as_int (rtx op, unsigned int elt)
3897 rtx tmp = CONST_VECTOR_ELT (op, elt);
3898 if (GET_MODE (op) == V4SFmode
3899 || GET_MODE (op) == V2SFmode)
3900 tmp = gen_lowpart (SImode, tmp);
3901 return INTVAL (tmp);
3904 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3905 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3906 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3907 all items are set to the same value and contain COPIES replicas of the
3908 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3909 operand and the others are set to the value of the operand's msb. */
3912 vspltis_constant (rtx op, unsigned step, unsigned copies)
3914 enum machine_mode mode = GET_MODE (op);
3915 enum machine_mode inner = GET_MODE_INNER (mode);
3918 unsigned nunits = GET_MODE_NUNITS (mode);
3919 unsigned bitsize = GET_MODE_BITSIZE (inner);
3920 unsigned mask = GET_MODE_MASK (inner);
3922 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3923 HOST_WIDE_INT splat_val = val;
3924 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3926 /* Construct the value to be splatted, if possible. If not, return 0. */
3927 for (i = 2; i <= copies; i *= 2)
3929 HOST_WIDE_INT small_val;
3931 small_val = splat_val >> bitsize;
3933 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3935 splat_val = small_val;
3938 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3939 if (EASY_VECTOR_15 (splat_val))
3942 /* Also check if we can splat, and then add the result to itself. Do so if
3943 the value is positive, of if the splat instruction is using OP's mode;
3944 for splat_val < 0, the splat and the add should use the same mode. */
3945 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3946 && (splat_val >= 0 || (step == 1 && copies == 1)))
3949 /* Also check if are loading up the most significant bit which can be done by
3950 loading up -1 and shifting the value left by -1. */
3951 else if (EASY_VECTOR_MSB (splat_val, inner))
3957 /* Check if VAL is present in every STEP-th element, and the
3958 other elements are filled with its most significant bit. */
3959 for (i = 0; i < nunits - 1; ++i)
3961 HOST_WIDE_INT desired_val;
3962 if (((i + 1) & (step - 1)) == 0)
3965 desired_val = msb_val;
3967 if (desired_val != const_vector_elt_as_int (op, i))
3975 /* Return true if OP is of the given MODE and can be synthesized
3976 with a vspltisb, vspltish or vspltisw. */
3979 easy_altivec_constant (rtx op, enum machine_mode mode)
3981 unsigned step, copies;
3983 if (mode == VOIDmode)
3984 mode = GET_MODE (op);
3985 else if (mode != GET_MODE (op))
3988 /* Start with a vspltisw. */
3989 step = GET_MODE_NUNITS (mode) / 4;
3992 if (vspltis_constant (op, step, copies))
3995 /* Then try with a vspltish. */
4001 if (vspltis_constant (op, step, copies))
4004 /* And finally a vspltisb. */
4010 if (vspltis_constant (op, step, copies))
4016 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4017 result is OP. Abort if it is not possible. */
4020 gen_easy_altivec_constant (rtx op)
4022 enum machine_mode mode = GET_MODE (op);
4023 int nunits = GET_MODE_NUNITS (mode);
4024 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4025 unsigned step = nunits / 4;
4026 unsigned copies = 1;
4028 /* Start with a vspltisw. */
4029 if (vspltis_constant (op, step, copies))
4030 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4032 /* Then try with a vspltish. */
4038 if (vspltis_constant (op, step, copies))
4039 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4041 /* And finally a vspltisb. */
4047 if (vspltis_constant (op, step, copies))
4048 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4054 output_vec_const_move (rtx *operands)
4057 enum machine_mode mode;
4062 mode = GET_MODE (dest);
4064 if (TARGET_VSX && zero_constant (vec, mode))
4065 return "xxlxor %x0,%x0,%x0";
4070 if (zero_constant (vec, mode))
4071 return "vxor %0,%0,%0";
4073 splat_vec = gen_easy_altivec_constant (vec);
4074 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4075 operands[1] = XEXP (splat_vec, 0);
4076 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4079 switch (GET_MODE (splat_vec))
4082 return "vspltisw %0,%1";
4085 return "vspltish %0,%1";
4088 return "vspltisb %0,%1";
4095 gcc_assert (TARGET_SPE);
4097 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4098 pattern of V1DI, V4HI, and V2SF.
4100 FIXME: We should probably return # and add post reload
4101 splitters for these, but this way is so easy ;-). */
4102 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4103 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4104 operands[1] = CONST_VECTOR_ELT (vec, 0);
4105 operands[2] = CONST_VECTOR_ELT (vec, 1);
4107 return "li %0,%1\n\tevmergelo %0,%0,%0";
4109 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4112 /* Initialize TARGET of vector PAIRED to VALS. */
4115 paired_expand_vector_init (rtx target, rtx vals)
4117 enum machine_mode mode = GET_MODE (target);
4118 int n_elts = GET_MODE_NUNITS (mode);
4120 rtx x, new_rtx, tmp, constant_op, op1, op2;
4123 for (i = 0; i < n_elts; ++i)
4125 x = XVECEXP (vals, 0, i);
4126 if (!CONSTANT_P (x))
4131 /* Load from constant pool. */
4132 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4138 /* The vector is initialized only with non-constants. */
4139 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4140 XVECEXP (vals, 0, 1));
4142 emit_move_insn (target, new_rtx);
4146 /* One field is non-constant and the other one is a constant. Load the
4147 constant from the constant pool and use ps_merge instruction to
4148 construct the whole vector. */
4149 op1 = XVECEXP (vals, 0, 0);
4150 op2 = XVECEXP (vals, 0, 1);
4152 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4154 tmp = gen_reg_rtx (GET_MODE (constant_op));
4155 emit_move_insn (tmp, constant_op);
4157 if (CONSTANT_P (op1))
4158 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4160 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4162 emit_move_insn (target, new_rtx);
4166 paired_expand_vector_move (rtx operands[])
4168 rtx op0 = operands[0], op1 = operands[1];
4170 emit_move_insn (op0, op1);
4173 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4174 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4175 operands for the relation operation COND. This is a recursive
4179 paired_emit_vector_compare (enum rtx_code rcode,
4180 rtx dest, rtx op0, rtx op1,
4181 rtx cc_op0, rtx cc_op1)
4183 rtx tmp = gen_reg_rtx (V2SFmode);
4184 rtx tmp1, max, min, equal_zero;
4186 gcc_assert (TARGET_PAIRED_FLOAT);
4187 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4193 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4197 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4198 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4202 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4205 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4208 tmp1 = gen_reg_rtx (V2SFmode);
4209 max = gen_reg_rtx (V2SFmode);
4210 min = gen_reg_rtx (V2SFmode);
4211 equal_zero = gen_reg_rtx (V2SFmode);
4213 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4214 emit_insn (gen_selv2sf4
4215 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4216 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4217 emit_insn (gen_selv2sf4
4218 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4219 emit_insn (gen_subv2sf3 (tmp1, min, max));
4220 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4223 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4226 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4229 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4232 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4235 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4244 /* Emit vector conditional expression.
4245 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4246 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4249 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4250 rtx cond, rtx cc_op0, rtx cc_op1)
4252 enum rtx_code rcode = GET_CODE (cond);
4254 if (!TARGET_PAIRED_FLOAT)
4257 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4262 /* Initialize vector TARGET to VALS. */
4265 rs6000_expand_vector_init (rtx target, rtx vals)
4267 enum machine_mode mode = GET_MODE (target);
4268 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4269 int n_elts = GET_MODE_NUNITS (mode);
4270 int n_var = 0, one_var = -1;
4271 bool all_same = true, all_const_zero = true;
4275 for (i = 0; i < n_elts; ++i)
4277 x = XVECEXP (vals, 0, i);
4278 if (!CONSTANT_P (x))
4279 ++n_var, one_var = i;
4280 else if (x != CONST0_RTX (inner_mode))
4281 all_const_zero = false;
4283 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4289 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4290 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4291 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4293 /* Zero register. */
4294 emit_insn (gen_rtx_SET (VOIDmode, target,
4295 gen_rtx_XOR (mode, target, target)));
4298 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4300 /* Splat immediate. */
4301 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4306 /* Load from constant pool. */
4307 emit_move_insn (target, const_vec);
4312 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4313 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4317 rtx element = XVECEXP (vals, 0, 0);
4318 if (mode == V2DFmode)
4319 emit_insn (gen_vsx_splat_v2df (target, element));
4321 emit_insn (gen_vsx_splat_v2di (target, element));
4325 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4326 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4327 if (mode == V2DFmode)
4328 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4330 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4335 /* With single precision floating point on VSX, know that internally single
4336 precision is actually represented as a double, and either make 2 V2DF
4337 vectors, and convert these vectors to single precision, or do one
4338 conversion, and splat the result to the other elements. */
4339 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4343 rtx freg = gen_reg_rtx (V4SFmode);
4344 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4346 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4347 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4351 rtx dbl_even = gen_reg_rtx (V2DFmode);
4352 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4353 rtx flt_even = gen_reg_rtx (V4SFmode);
4354 rtx flt_odd = gen_reg_rtx (V4SFmode);
4356 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4357 copy_to_reg (XVECEXP (vals, 0, 0)),
4358 copy_to_reg (XVECEXP (vals, 0, 1))));
4359 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4360 copy_to_reg (XVECEXP (vals, 0, 2)),
4361 copy_to_reg (XVECEXP (vals, 0, 3))));
4362 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4363 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4364 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4369 /* Store value to stack temp. Load vector element. Splat. However, splat
4370 of 64-bit items is not supported on Altivec. */
4371 if (all_same && GET_MODE_SIZE (mode) <= 4)
4373 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4374 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4375 XVECEXP (vals, 0, 0));
4376 x = gen_rtx_UNSPEC (VOIDmode,
4377 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4378 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4380 gen_rtx_SET (VOIDmode,
4383 x = gen_rtx_VEC_SELECT (inner_mode, target,
4384 gen_rtx_PARALLEL (VOIDmode,
4385 gen_rtvec (1, const0_rtx)));
4386 emit_insn (gen_rtx_SET (VOIDmode, target,
4387 gen_rtx_VEC_DUPLICATE (mode, x)));
4391 /* One field is non-constant. Load constant then overwrite
4395 rtx copy = copy_rtx (vals);
4397 /* Load constant part of vector, substitute neighboring value for
4399 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4400 rs6000_expand_vector_init (target, copy);
4402 /* Insert variable. */
4403 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4407 /* Construct the vector in memory one field at a time
4408 and load the whole vector. */
4409 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4410 for (i = 0; i < n_elts; i++)
4411 emit_move_insn (adjust_address_nv (mem, inner_mode,
4412 i * GET_MODE_SIZE (inner_mode)),
4413 XVECEXP (vals, 0, i));
4414 emit_move_insn (target, mem);
4417 /* Set field ELT of TARGET to VAL. */
4420 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4422 enum machine_mode mode = GET_MODE (target);
4423 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4424 rtx reg = gen_reg_rtx (mode);
4426 int width = GET_MODE_SIZE (inner_mode);
4429 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4431 rtx (*set_func) (rtx, rtx, rtx, rtx)
4432 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4433 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4437 /* Load single variable value. */
4438 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4439 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4440 x = gen_rtx_UNSPEC (VOIDmode,
4441 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4442 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4444 gen_rtx_SET (VOIDmode,
4448 /* Linear sequence. */
4449 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4450 for (i = 0; i < 16; ++i)
4451 XVECEXP (mask, 0, i) = GEN_INT (i);
4453 /* Set permute mask to insert element into target. */
4454 for (i = 0; i < width; ++i)
4455 XVECEXP (mask, 0, elt*width + i)
4456 = GEN_INT (i + 0x10);
4457 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4458 x = gen_rtx_UNSPEC (mode,
4459 gen_rtvec (3, target, reg,
4460 force_reg (V16QImode, x)),
4462 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4465 /* Extract field ELT from VEC into TARGET. */
4468 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4470 enum machine_mode mode = GET_MODE (vec);
4471 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4474 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4476 rtx (*extract_func) (rtx, rtx, rtx)
4477 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4478 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4482 /* Allocate mode-sized buffer. */
4483 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4485 /* Add offset to field within buffer matching vector element. */
4486 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4488 /* Store single field into mode-sized buffer. */
4489 x = gen_rtx_UNSPEC (VOIDmode,
4490 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4491 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4493 gen_rtx_SET (VOIDmode,
4496 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4499 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4500 implement ANDing by the mask IN. */
4502 build_mask64_2_operands (rtx in, rtx *out)
4504 #if HOST_BITS_PER_WIDE_INT >= 64
4505 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4508 gcc_assert (GET_CODE (in) == CONST_INT);
4513 /* Assume c initially something like 0x00fff000000fffff. The idea
4514 is to rotate the word so that the middle ^^^^^^ group of zeros
4515 is at the MS end and can be cleared with an rldicl mask. We then
4516 rotate back and clear off the MS ^^ group of zeros with a
4518 c = ~c; /* c == 0xff000ffffff00000 */
4519 lsb = c & -c; /* lsb == 0x0000000000100000 */
4520 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4521 c = ~c; /* c == 0x00fff000000fffff */
4522 c &= -lsb; /* c == 0x00fff00000000000 */
4523 lsb = c & -c; /* lsb == 0x0000100000000000 */
4524 c = ~c; /* c == 0xff000fffffffffff */
4525 c &= -lsb; /* c == 0xff00000000000000 */
4527 while ((lsb >>= 1) != 0)
4528 shift++; /* shift == 44 on exit from loop */
4529 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4530 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4531 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4535 /* Assume c initially something like 0xff000f0000000000. The idea
4536 is to rotate the word so that the ^^^ middle group of zeros
4537 is at the LS end and can be cleared with an rldicr mask. We then
4538 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4540 lsb = c & -c; /* lsb == 0x0000010000000000 */
4541 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4542 c = ~c; /* c == 0x00fff0ffffffffff */
4543 c &= -lsb; /* c == 0x00fff00000000000 */
4544 lsb = c & -c; /* lsb == 0x0000100000000000 */
4545 c = ~c; /* c == 0xff000fffffffffff */
4546 c &= -lsb; /* c == 0xff00000000000000 */
4548 while ((lsb >>= 1) != 0)
4549 shift++; /* shift == 44 on exit from loop */
4550 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4551 m1 >>= shift; /* m1 == 0x0000000000000fff */
4552 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4555 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4556 masks will be all 1's. We are guaranteed more than one transition. */
4557 out[0] = GEN_INT (64 - shift);
4558 out[1] = GEN_INT (m1);
4559 out[2] = GEN_INT (shift);
4560 out[3] = GEN_INT (m2);
4568 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4571 invalid_e500_subreg (rtx op, enum machine_mode mode)
4573 if (TARGET_E500_DOUBLE)
4575 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4576 subreg:TI and reg:TF. Decimal float modes are like integer
4577 modes (only low part of each register used) for this
4579 if (GET_CODE (op) == SUBREG
4580 && (mode == SImode || mode == DImode || mode == TImode
4581 || mode == DDmode || mode == TDmode)
4582 && REG_P (SUBREG_REG (op))
4583 && (GET_MODE (SUBREG_REG (op)) == DFmode
4584 || GET_MODE (SUBREG_REG (op)) == TFmode))
4587 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4589 if (GET_CODE (op) == SUBREG
4590 && (mode == DFmode || mode == TFmode)
4591 && REG_P (SUBREG_REG (op))
4592 && (GET_MODE (SUBREG_REG (op)) == DImode
4593 || GET_MODE (SUBREG_REG (op)) == TImode
4594 || GET_MODE (SUBREG_REG (op)) == DDmode
4595 || GET_MODE (SUBREG_REG (op)) == TDmode))
4600 && GET_CODE (op) == SUBREG
4602 && REG_P (SUBREG_REG (op))
4603 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4609 /* AIX increases natural record alignment to doubleword if the first
4610 field is an FP double while the FP fields remain word aligned. */
4613 rs6000_special_round_type_align (tree type, unsigned int computed,
4614 unsigned int specified)
4616 unsigned int align = MAX (computed, specified);
4617 tree field = TYPE_FIELDS (type);
4619 /* Skip all non field decls */
4620 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4621 field = TREE_CHAIN (field);
4623 if (field != NULL && field != type)
4625 type = TREE_TYPE (field);
4626 while (TREE_CODE (type) == ARRAY_TYPE)
4627 type = TREE_TYPE (type);
4629 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4630 align = MAX (align, 64);
4636 /* Darwin increases record alignment to the natural alignment of
4640 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4641 unsigned int specified)
4643 unsigned int align = MAX (computed, specified);
4645 if (TYPE_PACKED (type))
4648 /* Find the first field, looking down into aggregates. */
4650 tree field = TYPE_FIELDS (type);
4651 /* Skip all non field decls */
4652 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4653 field = TREE_CHAIN (field);
4656 /* A packed field does not contribute any extra alignment. */
4657 if (DECL_PACKED (field))
4659 type = TREE_TYPE (field);
4660 while (TREE_CODE (type) == ARRAY_TYPE)
4661 type = TREE_TYPE (type);
4662 } while (AGGREGATE_TYPE_P (type));
4664 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4665 align = MAX (align, TYPE_ALIGN (type));
4670 /* Return 1 for an operand in small memory on V.4/eabi. */
4673 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4674 enum machine_mode mode ATTRIBUTE_UNUSED)
4679 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4682 if (DEFAULT_ABI != ABI_V4)
4685 /* Vector and float memory instructions have a limited offset on the
4686 SPE, so using a vector or float variable directly as an operand is
4689 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4692 if (GET_CODE (op) == SYMBOL_REF)
4695 else if (GET_CODE (op) != CONST
4696 || GET_CODE (XEXP (op, 0)) != PLUS
4697 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4698 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4703 rtx sum = XEXP (op, 0);
4704 HOST_WIDE_INT summand;
4706 /* We have to be careful here, because it is the referenced address
4707 that must be 32k from _SDA_BASE_, not just the symbol. */
4708 summand = INTVAL (XEXP (sum, 1));
4709 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4712 sym_ref = XEXP (sum, 0);
4715 return SYMBOL_REF_SMALL_P (sym_ref);
4721 /* Return true if either operand is a general purpose register. */
4724 gpr_or_gpr_p (rtx op0, rtx op1)
4726 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4727 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4731 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4734 reg_offset_addressing_ok_p (enum machine_mode mode)
4744 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4745 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4753 /* Paired vector modes. Only reg+reg addressing is valid. */
4754 if (TARGET_PAIRED_FLOAT)
4766 virtual_stack_registers_memory_p (rtx op)
4770 if (GET_CODE (op) == REG)
4771 regnum = REGNO (op);
4773 else if (GET_CODE (op) == PLUS
4774 && GET_CODE (XEXP (op, 0)) == REG
4775 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4776 regnum = REGNO (XEXP (op, 0));
4781 return (regnum >= FIRST_VIRTUAL_REGISTER
4782 && regnum <= LAST_VIRTUAL_REGISTER);
4786 constant_pool_expr_p (rtx op)
4790 split_const (op, &base, &offset);
4791 return (GET_CODE (base) == SYMBOL_REF
4792 && CONSTANT_POOL_ADDRESS_P (base)
4793 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4797 toc_relative_expr_p (rtx op)
4801 if (GET_CODE (op) != CONST)
4804 split_const (op, &base, &offset);
4805 return (GET_CODE (base) == UNSPEC
4806 && XINT (base, 1) == UNSPEC_TOCREL);
4810 legitimate_constant_pool_address_p (rtx x)
4813 && GET_CODE (x) == PLUS
4814 && GET_CODE (XEXP (x, 0)) == REG
4815 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4816 && toc_relative_expr_p (XEXP (x, 1)));
4820 legitimate_small_data_p (enum machine_mode mode, rtx x)
4822 return (DEFAULT_ABI == ABI_V4
4823 && !flag_pic && !TARGET_TOC
4824 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4825 && small_data_operand (x, mode));
4828 /* SPE offset addressing is limited to 5-bits worth of double words. */
4829 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4832 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4834 unsigned HOST_WIDE_INT offset, extra;
4836 if (GET_CODE (x) != PLUS)
4838 if (GET_CODE (XEXP (x, 0)) != REG)
4840 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4842 if (!reg_offset_addressing_ok_p (mode))
4843 return virtual_stack_registers_memory_p (x);
4844 if (legitimate_constant_pool_address_p (x))
4846 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4849 offset = INTVAL (XEXP (x, 1));
4857 /* SPE vector modes. */
4858 return SPE_CONST_OFFSET_OK (offset);
4861 if (TARGET_E500_DOUBLE)
4862 return SPE_CONST_OFFSET_OK (offset);
4864 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4866 if (VECTOR_MEM_VSX_P (DFmode))
4871 /* On e500v2, we may have:
4873 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4875 Which gets addressed with evldd instructions. */
4876 if (TARGET_E500_DOUBLE)
4877 return SPE_CONST_OFFSET_OK (offset);
4879 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4881 else if (offset & 3)
4886 if (TARGET_E500_DOUBLE)
4887 return (SPE_CONST_OFFSET_OK (offset)
4888 && SPE_CONST_OFFSET_OK (offset + 8));
4892 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4894 else if (offset & 3)
4905 return (offset < 0x10000) && (offset + extra < 0x10000);
4909 legitimate_indexed_address_p (rtx x, int strict)
4913 if (GET_CODE (x) != PLUS)
4919 /* Recognize the rtl generated by reload which we know will later be
4920 replaced with proper base and index regs. */
4922 && reload_in_progress
4923 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4927 return (REG_P (op0) && REG_P (op1)
4928 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4929 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4930 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4931 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4935 avoiding_indexed_address_p (enum machine_mode mode)
4937 /* Avoid indexed addressing for modes that have non-indexed
4938 load/store instruction forms. */
4939 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4943 legitimate_indirect_address_p (rtx x, int strict)
4945 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4949 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4951 if (!TARGET_MACHO || !flag_pic
4952 || mode != SImode || GET_CODE (x) != MEM)
4956 if (GET_CODE (x) != LO_SUM)
4958 if (GET_CODE (XEXP (x, 0)) != REG)
4960 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4964 return CONSTANT_P (x);
4968 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4970 if (GET_CODE (x) != LO_SUM)
4972 if (GET_CODE (XEXP (x, 0)) != REG)
4974 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4976 /* Restrict addressing for DI because of our SUBREG hackery. */
4977 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4978 || mode == DDmode || mode == TDmode
4983 if (TARGET_ELF || TARGET_MACHO)
4985 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4989 if (GET_MODE_NUNITS (mode) != 1)
4991 if (GET_MODE_BITSIZE (mode) > 64
4992 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4993 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4994 && (mode == DFmode || mode == DDmode))))
4997 return CONSTANT_P (x);
5004 /* Try machine-dependent ways of modifying an illegitimate address
5005 to be legitimate. If we find one, return the new, valid address.
5006 This is used from only one place: `memory_address' in explow.c.
5008 OLDX is the address as it was before break_out_memory_refs was
5009 called. In some cases it is useful to look at this to decide what
5012 It is always safe for this function to do nothing. It exists to
5013 recognize opportunities to optimize the output.
5015 On RS/6000, first check for the sum of a register with a constant
5016 integer that is out of range. If so, generate code to add the
5017 constant with the low-order 16 bits masked to the register and force
5018 this result into another register (this can be done with `cau').
5019 Then generate an address of REG+(CONST&0xffff), allowing for the
5020 possibility of bit 16 being a one.
5022 Then check for the sum of a register and something not constant, try to
5023 load the other things into a register and return the sum. */
5026 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5027 enum machine_mode mode)
5029 unsigned int extra = 0;
5031 if (!reg_offset_addressing_ok_p (mode))
5033 if (virtual_stack_registers_memory_p (x))
5036 /* In theory we should not be seeing addresses of the form reg+0,
5037 but just in case it is generated, optimize it away. */
5038 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5039 return force_reg (Pmode, XEXP (x, 0));
5041 /* Make sure both operands are registers. */
5042 else if (GET_CODE (x) == PLUS)
5043 return gen_rtx_PLUS (Pmode,
5044 force_reg (Pmode, XEXP (x, 0)),
5045 force_reg (Pmode, XEXP (x, 1)));
5047 return force_reg (Pmode, x);
5049 if (GET_CODE (x) == SYMBOL_REF)
5051 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5053 return rs6000_legitimize_tls_address (x, model);
5063 if (!TARGET_POWERPC64)
5071 extra = TARGET_POWERPC64 ? 8 : 12;
5077 if (GET_CODE (x) == PLUS
5078 && GET_CODE (XEXP (x, 0)) == REG
5079 && GET_CODE (XEXP (x, 1)) == CONST_INT
5080 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5082 && !((TARGET_POWERPC64
5083 && (mode == DImode || mode == TImode)
5084 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5085 || SPE_VECTOR_MODE (mode)
5086 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5087 || mode == DImode || mode == DDmode
5088 || mode == TDmode))))
5090 HOST_WIDE_INT high_int, low_int;
5092 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5093 if (low_int >= 0x8000 - extra)
5095 high_int = INTVAL (XEXP (x, 1)) - low_int;
5096 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5097 GEN_INT (high_int)), 0);
5098 return plus_constant (sum, low_int);
5100 else if (GET_CODE (x) == PLUS
5101 && GET_CODE (XEXP (x, 0)) == REG
5102 && GET_CODE (XEXP (x, 1)) != CONST_INT
5103 && GET_MODE_NUNITS (mode) == 1
5104 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5106 || ((mode != DImode && mode != DFmode && mode != DDmode)
5107 || (TARGET_E500_DOUBLE && mode != DDmode)))
5108 && (TARGET_POWERPC64 || mode != DImode)
5109 && !avoiding_indexed_address_p (mode)
5114 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5115 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5117 else if (SPE_VECTOR_MODE (mode)
5118 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5119 || mode == DDmode || mode == TDmode
5120 || mode == DImode)))
5124 /* We accept [reg + reg] and [reg + OFFSET]. */
5126 if (GET_CODE (x) == PLUS)
5128 rtx op1 = XEXP (x, 0);
5129 rtx op2 = XEXP (x, 1);
5132 op1 = force_reg (Pmode, op1);
5134 if (GET_CODE (op2) != REG
5135 && (GET_CODE (op2) != CONST_INT
5136 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5137 || (GET_MODE_SIZE (mode) > 8
5138 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5139 op2 = force_reg (Pmode, op2);
5141 /* We can't always do [reg + reg] for these, because [reg +
5142 reg + offset] is not a legitimate addressing mode. */
5143 y = gen_rtx_PLUS (Pmode, op1, op2);
5145 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5146 return force_reg (Pmode, y);
5151 return force_reg (Pmode, x);
5157 && GET_CODE (x) != CONST_INT
5158 && GET_CODE (x) != CONST_DOUBLE
5160 && GET_MODE_NUNITS (mode) == 1
5161 && (GET_MODE_BITSIZE (mode) <= 32
5162 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5163 && (mode == DFmode || mode == DDmode))))
5165 rtx reg = gen_reg_rtx (Pmode);
5166 emit_insn (gen_elf_high (reg, x));
5167 return gen_rtx_LO_SUM (Pmode, reg, x);
5169 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5172 && ! MACHO_DYNAMIC_NO_PIC_P
5174 && GET_CODE (x) != CONST_INT
5175 && GET_CODE (x) != CONST_DOUBLE
5177 && GET_MODE_NUNITS (mode) == 1
5178 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5179 || (mode != DFmode && mode != DDmode))
5183 rtx reg = gen_reg_rtx (Pmode);
5184 emit_insn (gen_macho_high (reg, x));
5185 return gen_rtx_LO_SUM (Pmode, reg, x);
5188 && GET_CODE (x) == SYMBOL_REF
5189 && constant_pool_expr_p (x)
5190 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5192 return create_TOC_reference (x);
5198 /* Debug version of rs6000_legitimize_address. */
5200 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5206 ret = rs6000_legitimize_address (x, oldx, mode);
5207 insns = get_insns ();
5213 "\nrs6000_legitimize_address: mode %s, old code %s, "
5214 "new code %s, modified\n",
5215 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5216 GET_RTX_NAME (GET_CODE (ret)));
5218 fprintf (stderr, "Original address:\n");
5221 fprintf (stderr, "oldx:\n");
5224 fprintf (stderr, "New address:\n");
5229 fprintf (stderr, "Insns added:\n");
5230 debug_rtx_list (insns, 20);
5236 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5237 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5248 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5249 We need to emit DTP-relative relocations. */
5252 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5257 fputs ("\t.long\t", file);
5260 fputs (DOUBLE_INT_ASM_OP, file);
5265 output_addr_const (file, x);
5266 fputs ("@dtprel+0x8000", file);
5269 /* In the name of slightly smaller debug output, and to cater to
5270 general assembler lossage, recognize various UNSPEC sequences
5271 and turn them back into a direct symbol reference. */
5274 rs6000_delegitimize_address (rtx orig_x)
5278 orig_x = delegitimize_mem_from_attrs (orig_x);
5283 if (GET_CODE (x) == PLUS
5284 && GET_CODE (XEXP (x, 1)) == CONST
5285 && GET_CODE (XEXP (x, 0)) == REG
5286 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5288 y = XEXP (XEXP (x, 1), 0);
5289 if (GET_CODE (y) == UNSPEC
5290 && XINT (y, 1) == UNSPEC_TOCREL)
5292 y = XVECEXP (y, 0, 0);
5293 if (!MEM_P (orig_x))
5296 return replace_equiv_address_nv (orig_x, y);
5302 && GET_CODE (orig_x) == LO_SUM
5303 && GET_CODE (XEXP (x, 1)) == CONST)
5305 y = XEXP (XEXP (x, 1), 0);
5306 if (GET_CODE (y) == UNSPEC
5307 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5308 return XVECEXP (y, 0, 0);
5314 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5316 static GTY(()) rtx rs6000_tls_symbol;
5318 rs6000_tls_get_addr (void)
5320 if (!rs6000_tls_symbol)
5321 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5323 return rs6000_tls_symbol;
5326 /* Construct the SYMBOL_REF for TLS GOT references. */
5328 static GTY(()) rtx rs6000_got_symbol;
5330 rs6000_got_sym (void)
5332 if (!rs6000_got_symbol)
5334 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5335 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5336 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5339 return rs6000_got_symbol;
5342 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5343 this (thread-local) address. */
5346 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5350 dest = gen_reg_rtx (Pmode);
5351 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5357 tlsreg = gen_rtx_REG (Pmode, 13);
5358 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5362 tlsreg = gen_rtx_REG (Pmode, 2);
5363 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5367 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5371 tmp = gen_reg_rtx (Pmode);
5374 tlsreg = gen_rtx_REG (Pmode, 13);
5375 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5379 tlsreg = gen_rtx_REG (Pmode, 2);
5380 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5384 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5386 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5391 rtx r3, got, tga, tmp1, tmp2, eqv;
5393 /* We currently use relocations like @got@tlsgd for tls, which
5394 means the linker will handle allocation of tls entries, placing
5395 them in the .got section. So use a pointer to the .got section,
5396 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5397 or to secondary GOT sections used by 32-bit -fPIC. */
5399 got = gen_rtx_REG (Pmode, 2);
5403 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5406 rtx gsym = rs6000_got_sym ();
5407 got = gen_reg_rtx (Pmode);
5409 rs6000_emit_move (got, gsym, Pmode);
5415 tmp1 = gen_reg_rtx (Pmode);
5416 tmp2 = gen_reg_rtx (Pmode);
5417 tmp3 = gen_reg_rtx (Pmode);
5418 mem = gen_const_mem (Pmode, tmp1);
5420 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5421 emit_move_insn (tmp1,
5422 gen_rtx_REG (Pmode, LR_REGNO));
5423 emit_move_insn (tmp2, mem);
5424 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5425 last = emit_move_insn (got, tmp3);
5426 set_unique_reg_note (last, REG_EQUAL, gsym);
5431 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5433 r3 = gen_rtx_REG (Pmode, 3);
5434 tga = rs6000_tls_get_addr ();
5436 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5437 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5438 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5439 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5440 else if (DEFAULT_ABI == ABI_V4)
5441 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5446 insn = emit_call_insn (insn);
5447 RTL_CONST_CALL_P (insn) = 1;
5448 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5449 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5450 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5451 insn = get_insns ();
5453 emit_libcall_block (insn, dest, r3, addr);
5455 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5457 r3 = gen_rtx_REG (Pmode, 3);
5458 tga = rs6000_tls_get_addr ();
5460 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5461 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5462 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5463 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5464 else if (DEFAULT_ABI == ABI_V4)
5465 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5470 insn = emit_call_insn (insn);
5471 RTL_CONST_CALL_P (insn) = 1;
5472 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5473 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5474 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5475 insn = get_insns ();
5477 tmp1 = gen_reg_rtx (Pmode);
5478 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5480 emit_libcall_block (insn, tmp1, r3, eqv);
5481 if (rs6000_tls_size == 16)
5484 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5486 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5488 else if (rs6000_tls_size == 32)
5490 tmp2 = gen_reg_rtx (Pmode);
5492 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5494 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5497 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5499 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5503 tmp2 = gen_reg_rtx (Pmode);
5505 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5507 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5509 insn = gen_rtx_SET (Pmode, dest,
5510 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5516 /* IE, or 64-bit offset LE. */
5517 tmp2 = gen_reg_rtx (Pmode);
5519 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5521 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5524 insn = gen_tls_tls_64 (dest, tmp2, addr);
5526 insn = gen_tls_tls_32 (dest, tmp2, addr);
5534 /* Return 1 if X contains a thread-local symbol. */
5537 rs6000_tls_referenced_p (rtx x)
5539 if (! TARGET_HAVE_TLS)
5542 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5545 /* Return 1 if *X is a thread-local symbol. This is the same as
5546 rs6000_tls_symbol_ref except for the type of the unused argument. */
5549 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5551 return RS6000_SYMBOL_REF_TLS_P (*x);
5554 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5555 replace the input X, or the original X if no replacement is called for.
5556 The output parameter *WIN is 1 if the calling macro should goto WIN,
5559 For RS/6000, we wish to handle large displacements off a base
5560 register by splitting the addend across an addiu/addis and the mem insn.
5561 This cuts number of extra insns needed from 3 to 1.
5563 On Darwin, we use this to generate code for floating point constants.
5564 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5565 The Darwin code is inside #if TARGET_MACHO because only then are the
5566 machopic_* functions defined. */
5568 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5569 int opnum, int type,
5570 int ind_levels ATTRIBUTE_UNUSED, int *win)
5572 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5574 /* We must recognize output that we have already generated ourselves. */
5575 if (GET_CODE (x) == PLUS
5576 && GET_CODE (XEXP (x, 0)) == PLUS
5577 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5578 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5579 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5581 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5582 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5583 opnum, (enum reload_type)type);
5589 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5590 && GET_CODE (x) == LO_SUM
5591 && GET_CODE (XEXP (x, 0)) == PLUS
5592 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5593 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5594 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5595 && machopic_operand_p (XEXP (x, 1)))
5597 /* Result of previous invocation of this function on Darwin
5598 floating point constant. */
5599 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5600 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5601 opnum, (enum reload_type)type);
5607 /* Force ld/std non-word aligned offset into base register by wrapping
5609 if (GET_CODE (x) == PLUS
5610 && GET_CODE (XEXP (x, 0)) == REG
5611 && REGNO (XEXP (x, 0)) < 32
5612 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5613 && GET_CODE (XEXP (x, 1)) == CONST_INT
5615 && (INTVAL (XEXP (x, 1)) & 3) != 0
5616 && VECTOR_MEM_NONE_P (mode)
5617 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5618 && TARGET_POWERPC64)
5620 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5621 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5622 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5623 opnum, (enum reload_type) type);
5628 if (GET_CODE (x) == PLUS
5629 && GET_CODE (XEXP (x, 0)) == REG
5630 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5631 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5632 && GET_CODE (XEXP (x, 1)) == CONST_INT
5634 && !SPE_VECTOR_MODE (mode)
5635 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5636 || mode == DDmode || mode == TDmode
5638 && VECTOR_MEM_NONE_P (mode))
5640 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5641 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5643 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5645 /* Check for 32-bit overflow. */
5646 if (high + low != val)
5652 /* Reload the high part into a base reg; leave the low part
5653 in the mem directly. */
5655 x = gen_rtx_PLUS (GET_MODE (x),
5656 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5660 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5661 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5662 opnum, (enum reload_type)type);
5667 if (GET_CODE (x) == SYMBOL_REF
5669 && VECTOR_MEM_NONE_P (mode)
5670 && !SPE_VECTOR_MODE (mode)
5672 && DEFAULT_ABI == ABI_DARWIN
5673 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5675 && DEFAULT_ABI == ABI_V4
5678 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5679 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5683 && (mode != DImode || TARGET_POWERPC64)
5684 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5685 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5690 rtx offset = machopic_gen_offset (x);
5691 x = gen_rtx_LO_SUM (GET_MODE (x),
5692 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5693 gen_rtx_HIGH (Pmode, offset)), offset);
5697 x = gen_rtx_LO_SUM (GET_MODE (x),
5698 gen_rtx_HIGH (Pmode, x), x);
5700 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5701 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5702 opnum, (enum reload_type)type);
5707 /* Reload an offset address wrapped by an AND that represents the
5708 masking of the lower bits. Strip the outer AND and let reload
5709 convert the offset address into an indirect address. For VSX,
5710 force reload to create the address with an AND in a separate
5711 register, because we can't guarantee an altivec register will
5713 if (VECTOR_MEM_ALTIVEC_P (mode)
5714 && GET_CODE (x) == AND
5715 && GET_CODE (XEXP (x, 0)) == PLUS
5716 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5717 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5718 && GET_CODE (XEXP (x, 1)) == CONST_INT
5719 && INTVAL (XEXP (x, 1)) == -16)
5728 && GET_CODE (x) == SYMBOL_REF
5729 && constant_pool_expr_p (x)
5730 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5732 x = create_TOC_reference (x);
5740 /* Debug version of rs6000_legitimize_reload_address. */
5742 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5743 int opnum, int type,
5744 int ind_levels, int *win)
5746 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5749 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5750 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5751 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5755 fprintf (stderr, "Same address returned\n");
5757 fprintf (stderr, "NULL returned\n");
5760 fprintf (stderr, "New address:\n");
5767 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5768 that is a valid memory address for an instruction.
5769 The MODE argument is the machine mode for the MEM expression
5770 that wants to use this address.
5772 On the RS/6000, there are four valid address: a SYMBOL_REF that
5773 refers to a constant pool entry of an address (or the sum of it
5774 plus a constant), a short (16-bit signed) constant plus a register,
5775 the sum of two registers, or a register indirect, possibly with an
5776 auto-increment. For DFmode, DDmode and DImode with a constant plus
5777 register, we must ensure that both words are addressable or PowerPC64
5778 with offset word aligned.
5780 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5781 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5782 because adjacent memory cells are accessed by adding word-sized offsets
5783 during assembly output. */
5785 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5787 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5789 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5790 if (VECTOR_MEM_ALTIVEC_P (mode)
5791 && GET_CODE (x) == AND
5792 && GET_CODE (XEXP (x, 1)) == CONST_INT
5793 && INTVAL (XEXP (x, 1)) == -16)
5796 if (RS6000_SYMBOL_REF_TLS_P (x))
5798 if (legitimate_indirect_address_p (x, reg_ok_strict))
5800 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5801 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5802 && !SPE_VECTOR_MODE (mode)
5805 /* Restrict addressing for DI because of our SUBREG hackery. */
5806 && !(TARGET_E500_DOUBLE
5807 && (mode == DFmode || mode == DDmode || mode == DImode))
5809 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5811 if (virtual_stack_registers_memory_p (x))
5813 if (reg_offset_p && legitimate_small_data_p (mode, x))
5815 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5817 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5820 && GET_CODE (x) == PLUS
5821 && GET_CODE (XEXP (x, 0)) == REG
5822 && (XEXP (x, 0) == virtual_stack_vars_rtx
5823 || XEXP (x, 0) == arg_pointer_rtx)
5824 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5826 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5831 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5833 || (mode != DFmode && mode != DDmode)
5834 || (TARGET_E500_DOUBLE && mode != DDmode))
5835 && (TARGET_POWERPC64 || mode != DImode)
5836 && !avoiding_indexed_address_p (mode)
5837 && legitimate_indexed_address_p (x, reg_ok_strict))
5839 if (GET_CODE (x) == PRE_MODIFY
5843 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5845 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5846 && (TARGET_POWERPC64 || mode != DImode)
5847 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5848 && !SPE_VECTOR_MODE (mode)
5849 /* Restrict addressing for DI because of our SUBREG hackery. */
5850 && !(TARGET_E500_DOUBLE
5851 && (mode == DFmode || mode == DDmode || mode == DImode))
5853 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5854 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5855 || (!avoiding_indexed_address_p (mode)
5856 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5857 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5859 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5864 /* Debug version of rs6000_legitimate_address_p. */
5866 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5869 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5871 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5872 "strict = %d, code = %s\n",
5873 ret ? "true" : "false",
5874 GET_MODE_NAME (mode),
5876 GET_RTX_NAME (GET_CODE (x)));
5882 /* Go to LABEL if ADDR (a legitimate address expression)
5883 has an effect that depends on the machine mode it is used for.
5885 On the RS/6000 this is true of all integral offsets (since AltiVec
5886 and VSX modes don't allow them) or is a pre-increment or decrement.
5888 ??? Except that due to conceptual problems in offsettable_address_p
5889 we can't really report the problems of integral offsets. So leave
5890 this assuming that the adjustable offset must be valid for the
5891 sub-words of a TFmode operand, which is what we had before. */
5894 rs6000_mode_dependent_address (rtx addr)
5896 switch (GET_CODE (addr))
5899 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5900 is considered a legitimate address before reload, so there
5901 are no offset restrictions in that case. Note that this
5902 condition is safe in strict mode because any address involving
5903 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5904 been rejected as illegitimate. */
5905 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5906 && XEXP (addr, 0) != arg_pointer_rtx
5907 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5909 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5910 return val + 12 + 0x8000 >= 0x10000;
5917 /* Auto-increment cases are now treated generically in recog.c. */
5919 return TARGET_UPDATE;
5921 /* AND is only allowed in Altivec loads. */
5932 /* Debug version of rs6000_mode_dependent_address. */
5934 rs6000_debug_mode_dependent_address (rtx addr)
5936 bool ret = rs6000_mode_dependent_address (addr);
5938 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5939 ret ? "true" : "false");
5945 /* Implement FIND_BASE_TERM. */
5948 rs6000_find_base_term (rtx op)
5952 split_const (op, &base, &offset);
5953 if (GET_CODE (base) == UNSPEC)
5954 switch (XINT (base, 1))
5957 case UNSPEC_MACHOPIC_OFFSET:
5958 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5959 for aliasing purposes. */
5960 return XVECEXP (base, 0, 0);
5966 /* More elaborate version of recog's offsettable_memref_p predicate
5967 that works around the ??? note of rs6000_mode_dependent_address.
5968 In particular it accepts
5970 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5972 in 32-bit mode, that the recog predicate rejects. */
5975 rs6000_offsettable_memref_p (rtx op)
5980 /* First mimic offsettable_memref_p. */
5981 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5984 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5985 the latter predicate knows nothing about the mode of the memory
5986 reference and, therefore, assumes that it is the largest supported
5987 mode (TFmode). As a consequence, legitimate offsettable memory
5988 references are rejected. rs6000_legitimate_offset_address_p contains
5989 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5990 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5993 /* Change register usage conditional on target flags. */
5995 rs6000_conditional_register_usage (void)
5999 /* Set MQ register fixed (already call_used) if not POWER
6000 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6005 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6007 fixed_regs[13] = call_used_regs[13]
6008 = call_really_used_regs[13] = 1;
6010 /* Conditionally disable FPRs. */
6011 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6012 for (i = 32; i < 64; i++)
6013 fixed_regs[i] = call_used_regs[i]
6014 = call_really_used_regs[i] = 1;
6016 /* The TOC register is not killed across calls in a way that is
6017 visible to the compiler. */
6018 if (DEFAULT_ABI == ABI_AIX)
6019 call_really_used_regs[2] = 0;
6021 if (DEFAULT_ABI == ABI_V4
6022 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6024 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6026 if (DEFAULT_ABI == ABI_V4
6027 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6029 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6030 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6031 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6033 if (DEFAULT_ABI == ABI_DARWIN
6034 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6035 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6036 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6037 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6039 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6040 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6041 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6045 global_regs[SPEFSCR_REGNO] = 1;
6046 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6047 registers in prologues and epilogues. We no longer use r14
6048 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6049 pool for link-compatibility with older versions of GCC. Once
6050 "old" code has died out, we can return r14 to the allocation
6053 = call_used_regs[14]
6054 = call_really_used_regs[14] = 1;
6057 if (!TARGET_ALTIVEC && !TARGET_VSX)
6059 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6060 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6061 call_really_used_regs[VRSAVE_REGNO] = 1;
6064 if (TARGET_ALTIVEC || TARGET_VSX)
6065 global_regs[VSCR_REGNO] = 1;
6067 if (TARGET_ALTIVEC_ABI)
6069 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6070 call_used_regs[i] = call_really_used_regs[i] = 1;
6072 /* AIX reserves VR20:31 in non-extended ABI mode. */
6074 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6075 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6079 /* Try to output insns to set TARGET equal to the constant C if it can
6080 be done in less than N insns. Do all computations in MODE.
6081 Returns the place where the output has been placed if it can be
6082 done and the insns have been emitted. If it would take more than N
6083 insns, zero is returned and no insns and emitted. */
6086 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6087 rtx source, int n ATTRIBUTE_UNUSED)
6089 rtx result, insn, set;
6090 HOST_WIDE_INT c0, c1;
6097 dest = gen_reg_rtx (mode);
6098 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6102 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6104 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6105 GEN_INT (INTVAL (source)
6106 & (~ (HOST_WIDE_INT) 0xffff))));
6107 emit_insn (gen_rtx_SET (VOIDmode, dest,
6108 gen_rtx_IOR (SImode, copy_rtx (result),
6109 GEN_INT (INTVAL (source) & 0xffff))));
6114 switch (GET_CODE (source))
6117 c0 = INTVAL (source);
6122 #if HOST_BITS_PER_WIDE_INT >= 64
6123 c0 = CONST_DOUBLE_LOW (source);
6126 c0 = CONST_DOUBLE_LOW (source);
6127 c1 = CONST_DOUBLE_HIGH (source);
6135 result = rs6000_emit_set_long_const (dest, c0, c1);
6142 insn = get_last_insn ();
6143 set = single_set (insn);
6144 if (! CONSTANT_P (SET_SRC (set)))
6145 set_unique_reg_note (insn, REG_EQUAL, source);
6150 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6151 fall back to a straight forward decomposition. We do this to avoid
6152 exponential run times encountered when looking for longer sequences
6153 with rs6000_emit_set_const. */
6155 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6157 if (!TARGET_POWERPC64)
6159 rtx operand1, operand2;
6161 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6163 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6165 emit_move_insn (operand1, GEN_INT (c1));
6166 emit_move_insn (operand2, GEN_INT (c2));
6170 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6173 ud2 = (c1 & 0xffff0000) >> 16;
6174 #if HOST_BITS_PER_WIDE_INT >= 64
6178 ud4 = (c2 & 0xffff0000) >> 16;
6180 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6181 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6184 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6186 emit_move_insn (dest, GEN_INT (ud1));
6189 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6190 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6193 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6196 emit_move_insn (dest, GEN_INT (ud2 << 16));
6198 emit_move_insn (copy_rtx (dest),
6199 gen_rtx_IOR (DImode, copy_rtx (dest),
6202 else if (ud3 == 0 && ud4 == 0)
6204 gcc_assert (ud2 & 0x8000);
6205 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6208 emit_move_insn (copy_rtx (dest),
6209 gen_rtx_IOR (DImode, copy_rtx (dest),
6211 emit_move_insn (copy_rtx (dest),
6212 gen_rtx_ZERO_EXTEND (DImode,
6213 gen_lowpart (SImode,
6216 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6217 || (ud4 == 0 && ! (ud3 & 0x8000)))
6220 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6223 emit_move_insn (dest, GEN_INT (ud3 << 16));
6226 emit_move_insn (copy_rtx (dest),
6227 gen_rtx_IOR (DImode, copy_rtx (dest),
6229 emit_move_insn (copy_rtx (dest),
6230 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6233 emit_move_insn (copy_rtx (dest),
6234 gen_rtx_IOR (DImode, copy_rtx (dest),
6240 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6243 emit_move_insn (dest, GEN_INT (ud4 << 16));
6246 emit_move_insn (copy_rtx (dest),
6247 gen_rtx_IOR (DImode, copy_rtx (dest),
6250 emit_move_insn (copy_rtx (dest),
6251 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6254 emit_move_insn (copy_rtx (dest),
6255 gen_rtx_IOR (DImode, copy_rtx (dest),
6256 GEN_INT (ud2 << 16)));
6258 emit_move_insn (copy_rtx (dest),
6259 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6265 /* Helper for the following. Get rid of [r+r] memory refs
6266 in cases where it won't work (TImode, TFmode, TDmode). */
6269 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6271 if (GET_CODE (operands[0]) == MEM
6272 && GET_CODE (XEXP (operands[0], 0)) != REG
6273 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6274 && ! reload_in_progress)
6276 = replace_equiv_address (operands[0],
6277 copy_addr_to_reg (XEXP (operands[0], 0)));
6279 if (GET_CODE (operands[1]) == MEM
6280 && GET_CODE (XEXP (operands[1], 0)) != REG
6281 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6282 && ! reload_in_progress)
6284 = replace_equiv_address (operands[1],
6285 copy_addr_to_reg (XEXP (operands[1], 0)));
6288 /* Emit a move from SOURCE to DEST in mode MODE. */
6290 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6294 operands[1] = source;
6296 if (TARGET_DEBUG_ADDR)
6299 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6300 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6301 GET_MODE_NAME (mode),
6304 can_create_pseudo_p ());
6306 fprintf (stderr, "source:\n");
6310 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6311 if (GET_CODE (operands[1]) == CONST_DOUBLE
6312 && ! FLOAT_MODE_P (mode)
6313 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6315 /* FIXME. This should never happen. */
6316 /* Since it seems that it does, do the safe thing and convert
6318 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6320 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6321 || FLOAT_MODE_P (mode)
6322 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6323 || CONST_DOUBLE_LOW (operands[1]) < 0)
6324 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6325 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6327 /* Check if GCC is setting up a block move that will end up using FP
6328 registers as temporaries. We must make sure this is acceptable. */
6329 if (GET_CODE (operands[0]) == MEM
6330 && GET_CODE (operands[1]) == MEM
6332 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6333 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6334 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6335 ? 32 : MEM_ALIGN (operands[0])))
6336 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6338 : MEM_ALIGN (operands[1]))))
6339 && ! MEM_VOLATILE_P (operands [0])
6340 && ! MEM_VOLATILE_P (operands [1]))
6342 emit_move_insn (adjust_address (operands[0], SImode, 0),
6343 adjust_address (operands[1], SImode, 0));
6344 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6345 adjust_address (copy_rtx (operands[1]), SImode, 4));
6349 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6350 && !gpc_reg_operand (operands[1], mode))
6351 operands[1] = force_reg (mode, operands[1]);
6353 if (mode == SFmode && ! TARGET_POWERPC
6354 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6355 && GET_CODE (operands[0]) == MEM)
6359 if (reload_in_progress || reload_completed)
6360 regnum = true_regnum (operands[1]);
6361 else if (GET_CODE (operands[1]) == REG)
6362 regnum = REGNO (operands[1]);
6366 /* If operands[1] is a register, on POWER it may have
6367 double-precision data in it, so truncate it to single
6369 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6372 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6373 : gen_reg_rtx (mode));
6374 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6375 operands[1] = newreg;
6379 /* Recognize the case where operand[1] is a reference to thread-local
6380 data and load its address to a register. */
6381 if (rs6000_tls_referenced_p (operands[1]))
6383 enum tls_model model;
6384 rtx tmp = operands[1];
6387 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6389 addend = XEXP (XEXP (tmp, 0), 1);
6390 tmp = XEXP (XEXP (tmp, 0), 0);
6393 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6394 model = SYMBOL_REF_TLS_MODEL (tmp);
6395 gcc_assert (model != 0);
6397 tmp = rs6000_legitimize_tls_address (tmp, model);
6400 tmp = gen_rtx_PLUS (mode, tmp, addend);
6401 tmp = force_operand (tmp, operands[0]);
6406 /* Handle the case where reload calls us with an invalid address. */
6407 if (reload_in_progress && mode == Pmode
6408 && (! general_operand (operands[1], mode)
6409 || ! nonimmediate_operand (operands[0], mode)))
6412 /* 128-bit constant floating-point values on Darwin should really be
6413 loaded as two parts. */
6414 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6415 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6417 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6418 know how to get a DFmode SUBREG of a TFmode. */
6419 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6420 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6421 simplify_gen_subreg (imode, operands[1], mode, 0),
6423 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6424 GET_MODE_SIZE (imode)),
6425 simplify_gen_subreg (imode, operands[1], mode,
6426 GET_MODE_SIZE (imode)),
6431 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6432 cfun->machine->sdmode_stack_slot =
6433 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6435 if (reload_in_progress
6437 && MEM_P (operands[0])
6438 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6439 && REG_P (operands[1]))
6441 if (FP_REGNO_P (REGNO (operands[1])))
6443 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6444 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6445 emit_insn (gen_movsd_store (mem, operands[1]));
6447 else if (INT_REGNO_P (REGNO (operands[1])))
6449 rtx mem = adjust_address_nv (operands[0], mode, 4);
6450 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6451 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6457 if (reload_in_progress
6459 && REG_P (operands[0])
6460 && MEM_P (operands[1])
6461 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6463 if (FP_REGNO_P (REGNO (operands[0])))
6465 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6466 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6467 emit_insn (gen_movsd_load (operands[0], mem));
6469 else if (INT_REGNO_P (REGNO (operands[0])))
6471 rtx mem = adjust_address_nv (operands[1], mode, 4);
6472 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6473 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6480 /* FIXME: In the long term, this switch statement should go away
6481 and be replaced by a sequence of tests based on things like
6487 if (CONSTANT_P (operands[1])
6488 && GET_CODE (operands[1]) != CONST_INT)
6489 operands[1] = force_const_mem (mode, operands[1]);
6494 rs6000_eliminate_indexed_memrefs (operands);
6501 if (CONSTANT_P (operands[1])
6502 && ! easy_fp_constant (operands[1], mode))
6503 operands[1] = force_const_mem (mode, operands[1]);
6516 if (CONSTANT_P (operands[1])
6517 && !easy_vector_constant (operands[1], mode))
6518 operands[1] = force_const_mem (mode, operands[1]);
6523 /* Use default pattern for address of ELF small data */
6526 && DEFAULT_ABI == ABI_V4
6527 && (GET_CODE (operands[1]) == SYMBOL_REF
6528 || GET_CODE (operands[1]) == CONST)
6529 && small_data_operand (operands[1], mode))
6531 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6535 if (DEFAULT_ABI == ABI_V4
6536 && mode == Pmode && mode == SImode
6537 && flag_pic == 1 && got_operand (operands[1], mode))
6539 emit_insn (gen_movsi_got (operands[0], operands[1]));
6543 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6547 && CONSTANT_P (operands[1])
6548 && GET_CODE (operands[1]) != HIGH
6549 && GET_CODE (operands[1]) != CONST_INT)
6551 rtx target = (!can_create_pseudo_p ()
6553 : gen_reg_rtx (mode));
6555 /* If this is a function address on -mcall-aixdesc,
6556 convert it to the address of the descriptor. */
6557 if (DEFAULT_ABI == ABI_AIX
6558 && GET_CODE (operands[1]) == SYMBOL_REF
6559 && XSTR (operands[1], 0)[0] == '.')
6561 const char *name = XSTR (operands[1], 0);
6563 while (*name == '.')
6565 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6566 CONSTANT_POOL_ADDRESS_P (new_ref)
6567 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6568 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6569 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6570 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6571 operands[1] = new_ref;
6574 if (DEFAULT_ABI == ABI_DARWIN)
6577 if (MACHO_DYNAMIC_NO_PIC_P)
6579 /* Take care of any required data indirection. */
6580 operands[1] = rs6000_machopic_legitimize_pic_address (
6581 operands[1], mode, operands[0]);
6582 if (operands[0] != operands[1])
6583 emit_insn (gen_rtx_SET (VOIDmode,
6584 operands[0], operands[1]));
6588 emit_insn (gen_macho_high (target, operands[1]));
6589 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6593 emit_insn (gen_elf_high (target, operands[1]));
6594 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6598 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6599 and we have put it in the TOC, we just need to make a TOC-relative
6602 && GET_CODE (operands[1]) == SYMBOL_REF
6603 && constant_pool_expr_p (operands[1])
6604 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6605 get_pool_mode (operands[1])))
6607 operands[1] = create_TOC_reference (operands[1]);
6609 else if (mode == Pmode
6610 && CONSTANT_P (operands[1])
6611 && ((GET_CODE (operands[1]) != CONST_INT
6612 && ! easy_fp_constant (operands[1], mode))
6613 || (GET_CODE (operands[1]) == CONST_INT
6614 && num_insns_constant (operands[1], mode) > 2)
6615 || (GET_CODE (operands[0]) == REG
6616 && FP_REGNO_P (REGNO (operands[0]))))
6617 && GET_CODE (operands[1]) != HIGH
6618 && ! legitimate_constant_pool_address_p (operands[1])
6619 && ! toc_relative_expr_p (operands[1]))
6623 /* Darwin uses a special PIC legitimizer. */
6624 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6627 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6629 if (operands[0] != operands[1])
6630 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6635 /* If we are to limit the number of things we put in the TOC and
6636 this is a symbol plus a constant we can add in one insn,
6637 just put the symbol in the TOC and add the constant. Don't do
6638 this if reload is in progress. */
6639 if (GET_CODE (operands[1]) == CONST
6640 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6641 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6642 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6643 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6644 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6645 && ! side_effects_p (operands[0]))
6648 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6649 rtx other = XEXP (XEXP (operands[1], 0), 1);
6651 sym = force_reg (mode, sym);
6652 emit_insn (gen_add3_insn (operands[0], sym, other));
6656 operands[1] = force_const_mem (mode, operands[1]);
6659 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6660 && constant_pool_expr_p (XEXP (operands[1], 0))
6661 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6662 get_pool_constant (XEXP (operands[1], 0)),
6663 get_pool_mode (XEXP (operands[1], 0))))
6666 = gen_const_mem (mode,
6667 create_TOC_reference (XEXP (operands[1], 0)));
6668 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6674 rs6000_eliminate_indexed_memrefs (operands);
6678 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6680 gen_rtx_SET (VOIDmode,
6681 operands[0], operands[1]),
6682 gen_rtx_CLOBBER (VOIDmode,
6683 gen_rtx_SCRATCH (SImode)))));
6689 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6692 /* Above, we may have called force_const_mem which may have returned
6693 an invalid address. If we can, fix this up; otherwise, reload will
6694 have to deal with it. */
6695 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6696 operands[1] = validize_mem (operands[1]);
6699 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6702 /* Nonzero if we can use a floating-point register to pass this arg. */
6703 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6704 (SCALAR_FLOAT_MODE_P (MODE) \
6705 && (CUM)->fregno <= FP_ARG_MAX_REG \
6706 && TARGET_HARD_FLOAT && TARGET_FPRS)
6708 /* Nonzero if we can use an AltiVec register to pass this arg. */
6709 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6710 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6711 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6712 && TARGET_ALTIVEC_ABI \
6715 /* Return a nonzero value to say to return the function value in
6716 memory, just as large structures are always returned. TYPE will be
6717 the data type of the value, and FNTYPE will be the type of the
6718 function doing the returning, or @code{NULL} for libcalls.
6720 The AIX ABI for the RS/6000 specifies that all structures are
6721 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6722 specifies that structures <= 8 bytes are returned in r3/r4, but a
6723 draft put them in memory, and GCC used to implement the draft
6724 instead of the final standard. Therefore, aix_struct_return
6725 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6726 compatibility can change DRAFT_V4_STRUCT_RET to override the
6727 default, and -m switches get the final word. See
6728 rs6000_override_options for more details.
6730 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6731 long double support is enabled. These values are returned in memory.
6733 int_size_in_bytes returns -1 for variable size objects, which go in
6734 memory always. The cast to unsigned makes -1 > 8. */
6737 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6739 /* In the darwin64 abi, try to use registers for larger structs
6741 if (rs6000_darwin64_abi
6742 && TREE_CODE (type) == RECORD_TYPE
6743 && int_size_in_bytes (type) > 0)
6745 CUMULATIVE_ARGS valcum;
6749 valcum.fregno = FP_ARG_MIN_REG;
6750 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6751 /* Do a trial code generation as if this were going to be passed
6752 as an argument; if any part goes in memory, we return NULL. */
6753 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6756 /* Otherwise fall through to more conventional ABI rules. */
6759 if (AGGREGATE_TYPE_P (type)
6760 && (aix_struct_return
6761 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6764 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6765 modes only exist for GCC vector types if -maltivec. */
6766 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6767 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6770 /* Return synthetic vectors in memory. */
6771 if (TREE_CODE (type) == VECTOR_TYPE
6772 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6774 static bool warned_for_return_big_vectors = false;
6775 if (!warned_for_return_big_vectors)
6777 warning (0, "GCC vector returned by reference: "
6778 "non-standard ABI extension with no compatibility guarantee");
6779 warned_for_return_big_vectors = true;
6784 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6790 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6791 for a call to a function whose data type is FNTYPE.
6792 For a library call, FNTYPE is 0.
6794 For incoming args we set the number of arguments in the prototype large
6795 so we never return a PARALLEL. */
6798 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6799 rtx libname ATTRIBUTE_UNUSED, int incoming,
6800 int libcall, int n_named_args)
6802 static CUMULATIVE_ARGS zero_cumulative;
6804 *cum = zero_cumulative;
6806 cum->fregno = FP_ARG_MIN_REG;
6807 cum->vregno = ALTIVEC_ARG_MIN_REG;
6808 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6809 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6810 ? CALL_LIBCALL : CALL_NORMAL);
6811 cum->sysv_gregno = GP_ARG_MIN_REG;
6812 cum->stdarg = fntype
6813 && (TYPE_ARG_TYPES (fntype) != 0
6814 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6815 != void_type_node));
6817 cum->nargs_prototype = 0;
6818 if (incoming || cum->prototype)
6819 cum->nargs_prototype = n_named_args;
6821 /* Check for a longcall attribute. */
6822 if ((!fntype && rs6000_default_long_calls)
6824 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6825 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6826 cum->call_cookie |= CALL_LONG;
6828 if (TARGET_DEBUG_ARG)
6830 fprintf (stderr, "\ninit_cumulative_args:");
6833 tree ret_type = TREE_TYPE (fntype);
6834 fprintf (stderr, " ret code = %s,",
6835 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6838 if (cum->call_cookie & CALL_LONG)
6839 fprintf (stderr, " longcall,");
6841 fprintf (stderr, " proto = %d, nargs = %d\n",
6842 cum->prototype, cum->nargs_prototype);
6847 && TARGET_ALTIVEC_ABI
6848 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6850 error ("cannot return value in vector register because"
6851 " altivec instructions are disabled, use -maltivec"
6856 /* Return true if TYPE must be passed on the stack and not in registers. */
6859 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6861 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6862 return must_pass_in_stack_var_size (mode, type);
6864 return must_pass_in_stack_var_size_or_pad (mode, type);
6867 /* If defined, a C expression which determines whether, and in which
6868 direction, to pad out an argument with extra space. The value
6869 should be of type `enum direction': either `upward' to pad above
6870 the argument, `downward' to pad below, or `none' to inhibit
6873 For the AIX ABI structs are always stored left shifted in their
6877 function_arg_padding (enum machine_mode mode, const_tree type)
6879 #ifndef AGGREGATE_PADDING_FIXED
6880 #define AGGREGATE_PADDING_FIXED 0
6882 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6883 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6886 if (!AGGREGATE_PADDING_FIXED)
6888 /* GCC used to pass structures of the same size as integer types as
6889 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6890 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6891 passed padded downward, except that -mstrict-align further
6892 muddied the water in that multi-component structures of 2 and 4
6893 bytes in size were passed padded upward.
6895 The following arranges for best compatibility with previous
6896 versions of gcc, but removes the -mstrict-align dependency. */
6897 if (BYTES_BIG_ENDIAN)
6899 HOST_WIDE_INT size = 0;
6901 if (mode == BLKmode)
6903 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6904 size = int_size_in_bytes (type);
6907 size = GET_MODE_SIZE (mode);
6909 if (size == 1 || size == 2 || size == 4)
6915 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6917 if (type != 0 && AGGREGATE_TYPE_P (type))
6921 /* Fall back to the default. */
6922 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6925 /* If defined, a C expression that gives the alignment boundary, in bits,
6926 of an argument with the specified mode and type. If it is not defined,
6927 PARM_BOUNDARY is used for all arguments.
6929 V.4 wants long longs and doubles to be double word aligned. Just
6930 testing the mode size is a boneheaded way to do this as it means
6931 that other types such as complex int are also double word aligned.
6932 However, we're stuck with this because changing the ABI might break
6933 existing library interfaces.
6935 Doubleword align SPE vectors.
6936 Quadword align Altivec vectors.
6937 Quadword align large synthetic vector types. */
6940 function_arg_boundary (enum machine_mode mode, tree type)
6942 if (DEFAULT_ABI == ABI_V4
6943 && (GET_MODE_SIZE (mode) == 8
6944 || (TARGET_HARD_FLOAT
6946 && (mode == TFmode || mode == TDmode))))
6948 else if (SPE_VECTOR_MODE (mode)
6949 || (type && TREE_CODE (type) == VECTOR_TYPE
6950 && int_size_in_bytes (type) >= 8
6951 && int_size_in_bytes (type) < 16))
6953 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6954 || (type && TREE_CODE (type) == VECTOR_TYPE
6955 && int_size_in_bytes (type) >= 16))
6957 else if (rs6000_darwin64_abi && mode == BLKmode
6958 && type && TYPE_ALIGN (type) > 64)
6961 return PARM_BOUNDARY;
6964 /* For a function parm of MODE and TYPE, return the starting word in
6965 the parameter area. NWORDS of the parameter area are already used. */
6968 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6971 unsigned int parm_offset;
6973 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6974 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6975 return nwords + (-(parm_offset + nwords) & align);
6978 /* Compute the size (in words) of a function argument. */
6980 static unsigned long
6981 rs6000_arg_size (enum machine_mode mode, tree type)
6985 if (mode != BLKmode)
6986 size = GET_MODE_SIZE (mode);
6988 size = int_size_in_bytes (type);
6991 return (size + 3) >> 2;
6993 return (size + 7) >> 3;
6996 /* Use this to flush pending int fields. */
6999 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7000 HOST_WIDE_INT bitpos)
7002 unsigned int startbit, endbit;
7003 int intregs, intoffset;
7004 enum machine_mode mode;
7006 if (cum->intoffset == -1)
7009 intoffset = cum->intoffset;
7010 cum->intoffset = -1;
7012 if (intoffset % BITS_PER_WORD != 0)
7014 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7016 if (mode == BLKmode)
7018 /* We couldn't find an appropriate mode, which happens,
7019 e.g., in packed structs when there are 3 bytes to load.
7020 Back intoffset back to the beginning of the word in this
7022 intoffset = intoffset & -BITS_PER_WORD;
7026 startbit = intoffset & -BITS_PER_WORD;
7027 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7028 intregs = (endbit - startbit) / BITS_PER_WORD;
7029 cum->words += intregs;
7032 /* The darwin64 ABI calls for us to recurse down through structs,
7033 looking for elements passed in registers. Unfortunately, we have
7034 to track int register count here also because of misalignments
7035 in powerpc alignment mode. */
7038 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7040 HOST_WIDE_INT startbitpos)
7044 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7045 if (TREE_CODE (f) == FIELD_DECL)
7047 HOST_WIDE_INT bitpos = startbitpos;
7048 tree ftype = TREE_TYPE (f);
7049 enum machine_mode mode;
7050 if (ftype == error_mark_node)
7052 mode = TYPE_MODE (ftype);
7054 if (DECL_SIZE (f) != 0
7055 && host_integerp (bit_position (f), 1))
7056 bitpos += int_bit_position (f);
7058 /* ??? FIXME: else assume zero offset. */
7060 if (TREE_CODE (ftype) == RECORD_TYPE)
7061 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7062 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7064 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7065 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7066 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7068 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7070 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7074 else if (cum->intoffset == -1)
7075 cum->intoffset = bitpos;
7079 /* Update the data in CUM to advance over an argument
7080 of mode MODE and data type TYPE.
7081 (TYPE is null for libcalls where that information may not be available.)
7083 Note that for args passed by reference, function_arg will be called
7084 with MODE and TYPE set to that of the pointer to the arg, not the arg
7088 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7089 tree type, int named, int depth)
7093 /* Only tick off an argument if we're not recursing. */
7095 cum->nargs_prototype--;
7097 if (TARGET_ALTIVEC_ABI
7098 && (ALTIVEC_VECTOR_MODE (mode)
7099 || VSX_VECTOR_MODE (mode)
7100 || (type && TREE_CODE (type) == VECTOR_TYPE
7101 && int_size_in_bytes (type) == 16)))
7105 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7108 if (!TARGET_ALTIVEC)
7109 error ("cannot pass argument in vector register because"
7110 " altivec instructions are disabled, use -maltivec"
7113 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7114 even if it is going to be passed in a vector register.
7115 Darwin does the same for variable-argument functions. */
7116 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7117 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7127 /* Vector parameters must be 16-byte aligned. This places
7128 them at 2 mod 4 in terms of words in 32-bit mode, since
7129 the parameter save area starts at offset 24 from the
7130 stack. In 64-bit mode, they just have to start on an
7131 even word, since the parameter save area is 16-byte
7132 aligned. Space for GPRs is reserved even if the argument
7133 will be passed in memory. */
7135 align = (2 - cum->words) & 3;
7137 align = cum->words & 1;
7138 cum->words += align + rs6000_arg_size (mode, type);
7140 if (TARGET_DEBUG_ARG)
7142 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7144 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7145 cum->nargs_prototype, cum->prototype,
7146 GET_MODE_NAME (mode));
7150 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7152 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7155 else if (rs6000_darwin64_abi
7157 && TREE_CODE (type) == RECORD_TYPE
7158 && (size = int_size_in_bytes (type)) > 0)
7160 /* Variable sized types have size == -1 and are
7161 treated as if consisting entirely of ints.
7162 Pad to 16 byte boundary if needed. */
7163 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7164 && (cum->words % 2) != 0)
7166 /* For varargs, we can just go up by the size of the struct. */
7168 cum->words += (size + 7) / 8;
7171 /* It is tempting to say int register count just goes up by
7172 sizeof(type)/8, but this is wrong in a case such as
7173 { int; double; int; } [powerpc alignment]. We have to
7174 grovel through the fields for these too. */
7176 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7177 rs6000_darwin64_record_arg_advance_flush (cum,
7178 size * BITS_PER_UNIT);
7181 else if (DEFAULT_ABI == ABI_V4)
7183 if (TARGET_HARD_FLOAT && TARGET_FPRS
7184 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7185 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7186 || (mode == TFmode && !TARGET_IEEEQUAD)
7187 || mode == SDmode || mode == DDmode || mode == TDmode))
7189 /* _Decimal128 must use an even/odd register pair. This assumes
7190 that the register number is odd when fregno is odd. */
7191 if (mode == TDmode && (cum->fregno % 2) == 1)
7194 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7195 <= FP_ARG_V4_MAX_REG)
7196 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7199 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7200 if (mode == DFmode || mode == TFmode
7201 || mode == DDmode || mode == TDmode)
7202 cum->words += cum->words & 1;
7203 cum->words += rs6000_arg_size (mode, type);
7208 int n_words = rs6000_arg_size (mode, type);
7209 int gregno = cum->sysv_gregno;
7211 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7212 (r7,r8) or (r9,r10). As does any other 2 word item such
7213 as complex int due to a historical mistake. */
7215 gregno += (1 - gregno) & 1;
7217 /* Multi-reg args are not split between registers and stack. */
7218 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7220 /* Long long and SPE vectors are aligned on the stack.
7221 So are other 2 word items such as complex int due to
7222 a historical mistake. */
7224 cum->words += cum->words & 1;
7225 cum->words += n_words;
7228 /* Note: continuing to accumulate gregno past when we've started
7229 spilling to the stack indicates the fact that we've started
7230 spilling to the stack to expand_builtin_saveregs. */
7231 cum->sysv_gregno = gregno + n_words;
7234 if (TARGET_DEBUG_ARG)
7236 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7237 cum->words, cum->fregno);
7238 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7239 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7240 fprintf (stderr, "mode = %4s, named = %d\n",
7241 GET_MODE_NAME (mode), named);
7246 int n_words = rs6000_arg_size (mode, type);
7247 int start_words = cum->words;
7248 int align_words = rs6000_parm_start (mode, type, start_words);
7250 cum->words = align_words + n_words;
7252 if (SCALAR_FLOAT_MODE_P (mode)
7253 && TARGET_HARD_FLOAT && TARGET_FPRS)
7255 /* _Decimal128 must be passed in an even/odd float register pair.
7256 This assumes that the register number is odd when fregno is
7258 if (mode == TDmode && (cum->fregno % 2) == 1)
7260 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7263 if (TARGET_DEBUG_ARG)
7265 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7266 cum->words, cum->fregno);
7267 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7268 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7269 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7270 named, align_words - start_words, depth);
7276 spe_build_register_parallel (enum machine_mode mode, int gregno)
7283 r1 = gen_rtx_REG (DImode, gregno);
7284 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7285 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7289 r1 = gen_rtx_REG (DImode, gregno);
7290 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7291 r3 = gen_rtx_REG (DImode, gregno + 2);
7292 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7293 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7296 r1 = gen_rtx_REG (DImode, gregno);
7297 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7298 r3 = gen_rtx_REG (DImode, gregno + 2);
7299 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7300 r5 = gen_rtx_REG (DImode, gregno + 4);
7301 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7302 r7 = gen_rtx_REG (DImode, gregno + 6);
7303 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7304 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7311 /* Determine where to put a SIMD argument on the SPE. */
7313 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7316 int gregno = cum->sysv_gregno;
7318 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7319 are passed and returned in a pair of GPRs for ABI compatibility. */
7320 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7321 || mode == DCmode || mode == TCmode))
7323 int n_words = rs6000_arg_size (mode, type);
7325 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7327 gregno += (1 - gregno) & 1;
7329 /* Multi-reg args are not split between registers and stack. */
7330 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7333 return spe_build_register_parallel (mode, gregno);
7337 int n_words = rs6000_arg_size (mode, type);
7339 /* SPE vectors are put in odd registers. */
7340 if (n_words == 2 && (gregno & 1) == 0)
7343 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7346 enum machine_mode m = SImode;
7348 r1 = gen_rtx_REG (m, gregno);
7349 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7350 r2 = gen_rtx_REG (m, gregno + 1);
7351 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7352 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7359 if (gregno <= GP_ARG_MAX_REG)
7360 return gen_rtx_REG (mode, gregno);
7366 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7367 structure between cum->intoffset and bitpos to integer registers. */
7370 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7371 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7373 enum machine_mode mode;
7375 unsigned int startbit, endbit;
7376 int this_regno, intregs, intoffset;
7379 if (cum->intoffset == -1)
7382 intoffset = cum->intoffset;
7383 cum->intoffset = -1;
7385 /* If this is the trailing part of a word, try to only load that
7386 much into the register. Otherwise load the whole register. Note
7387 that in the latter case we may pick up unwanted bits. It's not a
7388 problem at the moment but may wish to revisit. */
7390 if (intoffset % BITS_PER_WORD != 0)
7392 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7394 if (mode == BLKmode)
7396 /* We couldn't find an appropriate mode, which happens,
7397 e.g., in packed structs when there are 3 bytes to load.
7398 Back intoffset back to the beginning of the word in this
7400 intoffset = intoffset & -BITS_PER_WORD;
7407 startbit = intoffset & -BITS_PER_WORD;
7408 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7409 intregs = (endbit - startbit) / BITS_PER_WORD;
7410 this_regno = cum->words + intoffset / BITS_PER_WORD;
7412 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7415 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7419 intoffset /= BITS_PER_UNIT;
7422 regno = GP_ARG_MIN_REG + this_regno;
7423 reg = gen_rtx_REG (mode, regno);
7425 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7428 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7432 while (intregs > 0);
7435 /* Recursive workhorse for the following. */
7438 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7439 HOST_WIDE_INT startbitpos, rtx rvec[],
7444 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7445 if (TREE_CODE (f) == FIELD_DECL)
7447 HOST_WIDE_INT bitpos = startbitpos;
7448 tree ftype = TREE_TYPE (f);
7449 enum machine_mode mode;
7450 if (ftype == error_mark_node)
7452 mode = TYPE_MODE (ftype);
7454 if (DECL_SIZE (f) != 0
7455 && host_integerp (bit_position (f), 1))
7456 bitpos += int_bit_position (f);
7458 /* ??? FIXME: else assume zero offset. */
7460 if (TREE_CODE (ftype) == RECORD_TYPE)
7461 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7462 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7467 case SCmode: mode = SFmode; break;
7468 case DCmode: mode = DFmode; break;
7469 case TCmode: mode = TFmode; break;
7473 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7475 = gen_rtx_EXPR_LIST (VOIDmode,
7476 gen_rtx_REG (mode, cum->fregno++),
7477 GEN_INT (bitpos / BITS_PER_UNIT));
7478 if (mode == TFmode || mode == TDmode)
7481 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7483 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7485 = gen_rtx_EXPR_LIST (VOIDmode,
7486 gen_rtx_REG (mode, cum->vregno++),
7487 GEN_INT (bitpos / BITS_PER_UNIT));
7489 else if (cum->intoffset == -1)
7490 cum->intoffset = bitpos;
7494 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7495 the register(s) to be used for each field and subfield of a struct
7496 being passed by value, along with the offset of where the
7497 register's value may be found in the block. FP fields go in FP
7498 register, vector fields go in vector registers, and everything
7499 else goes in int registers, packed as in memory.
7501 This code is also used for function return values. RETVAL indicates
7502 whether this is the case.
7504 Much of this is taken from the SPARC V9 port, which has a similar
7505 calling convention. */
7508 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7509 int named, bool retval)
7511 rtx rvec[FIRST_PSEUDO_REGISTER];
7512 int k = 1, kbase = 1;
7513 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7514 /* This is a copy; modifications are not visible to our caller. */
7515 CUMULATIVE_ARGS copy_cum = *orig_cum;
7516 CUMULATIVE_ARGS *cum = ©_cum;
7518 /* Pad to 16 byte boundary if needed. */
7519 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7520 && (cum->words % 2) != 0)
7527 /* Put entries into rvec[] for individual FP and vector fields, and
7528 for the chunks of memory that go in int regs. Note we start at
7529 element 1; 0 is reserved for an indication of using memory, and
7530 may or may not be filled in below. */
7531 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7532 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7534 /* If any part of the struct went on the stack put all of it there.
7535 This hack is because the generic code for
7536 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7537 parts of the struct are not at the beginning. */
7541 return NULL_RTX; /* doesn't go in registers at all */
7543 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7545 if (k > 1 || cum->use_stack)
7546 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7551 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7554 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7558 rtx rvec[GP_ARG_NUM_REG + 1];
7560 if (align_words >= GP_ARG_NUM_REG)
7563 n_units = rs6000_arg_size (mode, type);
7565 /* Optimize the simple case where the arg fits in one gpr, except in
7566 the case of BLKmode due to assign_parms assuming that registers are
7567 BITS_PER_WORD wide. */
7569 || (n_units == 1 && mode != BLKmode))
7570 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7573 if (align_words + n_units > GP_ARG_NUM_REG)
7574 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7575 using a magic NULL_RTX component.
7576 This is not strictly correct. Only some of the arg belongs in
7577 memory, not all of it. However, the normal scheme using
7578 function_arg_partial_nregs can result in unusual subregs, eg.
7579 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7580 store the whole arg to memory is often more efficient than code
7581 to store pieces, and we know that space is available in the right
7582 place for the whole arg. */
7583 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7588 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7589 rtx off = GEN_INT (i++ * 4);
7590 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7592 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7594 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7597 /* Determine where to put an argument to a function.
7598 Value is zero to push the argument on the stack,
7599 or a hard register in which to store the argument.
7601 MODE is the argument's machine mode.
7602 TYPE is the data type of the argument (as a tree).
7603 This is null for libcalls where that information may
7605 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7606 the preceding args and about the function being called. It is
7607 not modified in this routine.
7608 NAMED is nonzero if this argument is a named parameter
7609 (otherwise it is an extra parameter matching an ellipsis).
7611 On RS/6000 the first eight words of non-FP are normally in registers
7612 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7613 Under V.4, the first 8 FP args are in registers.
7615 If this is floating-point and no prototype is specified, we use
7616 both an FP and integer register (or possibly FP reg and stack). Library
7617 functions (when CALL_LIBCALL is set) always have the proper types for args,
7618 so we can pass the FP value just in one register. emit_library_function
7619 doesn't support PARALLEL anyway.
7621 Note that for args passed by reference, function_arg will be called
7622 with MODE and TYPE set to that of the pointer to the arg, not the arg
7626 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7627 tree type, int named)
7629 enum rs6000_abi abi = DEFAULT_ABI;
7631 /* Return a marker to indicate whether CR1 needs to set or clear the
7632 bit that V.4 uses to say fp args were passed in registers.
7633 Assume that we don't need the marker for software floating point,
7634 or compiler generated library calls. */
7635 if (mode == VOIDmode)
7638 && (cum->call_cookie & CALL_LIBCALL) == 0
7640 || (cum->nargs_prototype < 0
7641 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7643 /* For the SPE, we need to crxor CR6 always. */
7645 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7646 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7647 return GEN_INT (cum->call_cookie
7648 | ((cum->fregno == FP_ARG_MIN_REG)
7649 ? CALL_V4_SET_FP_ARGS
7650 : CALL_V4_CLEAR_FP_ARGS));
7653 return GEN_INT (cum->call_cookie);
7656 if (rs6000_darwin64_abi && mode == BLKmode
7657 && TREE_CODE (type) == RECORD_TYPE)
7659 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7660 if (rslt != NULL_RTX)
7662 /* Else fall through to usual handling. */
7665 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7666 if (TARGET_64BIT && ! cum->prototype)
7668 /* Vector parameters get passed in vector register
7669 and also in GPRs or memory, in absence of prototype. */
7672 align_words = (cum->words + 1) & ~1;
7674 if (align_words >= GP_ARG_NUM_REG)
7680 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7682 return gen_rtx_PARALLEL (mode,
7684 gen_rtx_EXPR_LIST (VOIDmode,
7686 gen_rtx_EXPR_LIST (VOIDmode,
7687 gen_rtx_REG (mode, cum->vregno),
7691 return gen_rtx_REG (mode, cum->vregno);
7692 else if (TARGET_ALTIVEC_ABI
7693 && (ALTIVEC_VECTOR_MODE (mode)
7694 || VSX_VECTOR_MODE (mode)
7695 || (type && TREE_CODE (type) == VECTOR_TYPE
7696 && int_size_in_bytes (type) == 16)))
7698 if (named || abi == ABI_V4)
7702 /* Vector parameters to varargs functions under AIX or Darwin
7703 get passed in memory and possibly also in GPRs. */
7704 int align, align_words, n_words;
7705 enum machine_mode part_mode;
7707 /* Vector parameters must be 16-byte aligned. This places them at
7708 2 mod 4 in terms of words in 32-bit mode, since the parameter
7709 save area starts at offset 24 from the stack. In 64-bit mode,
7710 they just have to start on an even word, since the parameter
7711 save area is 16-byte aligned. */
7713 align = (2 - cum->words) & 3;
7715 align = cum->words & 1;
7716 align_words = cum->words + align;
7718 /* Out of registers? Memory, then. */
7719 if (align_words >= GP_ARG_NUM_REG)
7722 if (TARGET_32BIT && TARGET_POWERPC64)
7723 return rs6000_mixed_function_arg (mode, type, align_words);
7725 /* The vector value goes in GPRs. Only the part of the
7726 value in GPRs is reported here. */
7728 n_words = rs6000_arg_size (mode, type);
7729 if (align_words + n_words > GP_ARG_NUM_REG)
7730 /* Fortunately, there are only two possibilities, the value
7731 is either wholly in GPRs or half in GPRs and half not. */
7734 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7737 else if (TARGET_SPE_ABI && TARGET_SPE
7738 && (SPE_VECTOR_MODE (mode)
7739 || (TARGET_E500_DOUBLE && (mode == DFmode
7742 || mode == TCmode))))
7743 return rs6000_spe_function_arg (cum, mode, type);
7745 else if (abi == ABI_V4)
7747 if (TARGET_HARD_FLOAT && TARGET_FPRS
7748 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7749 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7750 || (mode == TFmode && !TARGET_IEEEQUAD)
7751 || mode == SDmode || mode == DDmode || mode == TDmode))
7753 /* _Decimal128 must use an even/odd register pair. This assumes
7754 that the register number is odd when fregno is odd. */
7755 if (mode == TDmode && (cum->fregno % 2) == 1)
7758 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7759 <= FP_ARG_V4_MAX_REG)
7760 return gen_rtx_REG (mode, cum->fregno);
7766 int n_words = rs6000_arg_size (mode, type);
7767 int gregno = cum->sysv_gregno;
7769 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7770 (r7,r8) or (r9,r10). As does any other 2 word item such
7771 as complex int due to a historical mistake. */
7773 gregno += (1 - gregno) & 1;
7775 /* Multi-reg args are not split between registers and stack. */
7776 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7779 if (TARGET_32BIT && TARGET_POWERPC64)
7780 return rs6000_mixed_function_arg (mode, type,
7781 gregno - GP_ARG_MIN_REG);
7782 return gen_rtx_REG (mode, gregno);
7787 int align_words = rs6000_parm_start (mode, type, cum->words);
7789 /* _Decimal128 must be passed in an even/odd float register pair.
7790 This assumes that the register number is odd when fregno is odd. */
7791 if (mode == TDmode && (cum->fregno % 2) == 1)
7794 if (USE_FP_FOR_ARG_P (cum, mode, type))
7796 rtx rvec[GP_ARG_NUM_REG + 1];
7800 enum machine_mode fmode = mode;
7801 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7803 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7805 /* Currently, we only ever need one reg here because complex
7806 doubles are split. */
7807 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7808 && (fmode == TFmode || fmode == TDmode));
7810 /* Long double or _Decimal128 split over regs and memory. */
7811 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7814 /* Do we also need to pass this arg in the parameter save
7817 && (cum->nargs_prototype <= 0
7818 || (DEFAULT_ABI == ABI_AIX
7820 && align_words >= GP_ARG_NUM_REG)));
7822 if (!needs_psave && mode == fmode)
7823 return gen_rtx_REG (fmode, cum->fregno);
7828 /* Describe the part that goes in gprs or the stack.
7829 This piece must come first, before the fprs. */
7830 if (align_words < GP_ARG_NUM_REG)
7832 unsigned long n_words = rs6000_arg_size (mode, type);
7834 if (align_words + n_words > GP_ARG_NUM_REG
7835 || (TARGET_32BIT && TARGET_POWERPC64))
7837 /* If this is partially on the stack, then we only
7838 include the portion actually in registers here. */
7839 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7842 if (align_words + n_words > GP_ARG_NUM_REG)
7843 /* Not all of the arg fits in gprs. Say that it
7844 goes in memory too, using a magic NULL_RTX
7845 component. Also see comment in
7846 rs6000_mixed_function_arg for why the normal
7847 function_arg_partial_nregs scheme doesn't work
7849 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7853 r = gen_rtx_REG (rmode,
7854 GP_ARG_MIN_REG + align_words);
7855 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7856 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7858 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7862 /* The whole arg fits in gprs. */
7863 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7864 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7868 /* It's entirely in memory. */
7869 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7872 /* Describe where this piece goes in the fprs. */
7873 r = gen_rtx_REG (fmode, cum->fregno);
7874 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7876 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7878 else if (align_words < GP_ARG_NUM_REG)
7880 if (TARGET_32BIT && TARGET_POWERPC64)
7881 return rs6000_mixed_function_arg (mode, type, align_words);
7883 if (mode == BLKmode)
7886 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7893 /* For an arg passed partly in registers and partly in memory, this is
7894 the number of bytes passed in registers. For args passed entirely in
7895 registers or entirely in memory, zero. When an arg is described by a
7896 PARALLEL, perhaps using more than one register type, this function
7897 returns the number of bytes used by the first element of the PARALLEL. */
7900 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7901 tree type, bool named)
7906 if (DEFAULT_ABI == ABI_V4)
7909 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7910 && cum->nargs_prototype >= 0)
7913 /* In this complicated case we just disable the partial_nregs code. */
7914 if (rs6000_darwin64_abi && mode == BLKmode
7915 && TREE_CODE (type) == RECORD_TYPE
7916 && int_size_in_bytes (type) > 0)
7919 align_words = rs6000_parm_start (mode, type, cum->words);
7921 if (USE_FP_FOR_ARG_P (cum, mode, type))
7923 /* If we are passing this arg in the fixed parameter save area
7924 (gprs or memory) as well as fprs, then this function should
7925 return the number of partial bytes passed in the parameter
7926 save area rather than partial bytes passed in fprs. */
7928 && (cum->nargs_prototype <= 0
7929 || (DEFAULT_ABI == ABI_AIX
7931 && align_words >= GP_ARG_NUM_REG)))
7933 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7934 > FP_ARG_MAX_REG + 1)
7935 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7936 else if (cum->nargs_prototype >= 0)
7940 if (align_words < GP_ARG_NUM_REG
7941 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7942 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7944 if (ret != 0 && TARGET_DEBUG_ARG)
7945 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7950 /* A C expression that indicates when an argument must be passed by
7951 reference. If nonzero for an argument, a copy of that argument is
7952 made in memory and a pointer to the argument is passed instead of
7953 the argument itself. The pointer is passed in whatever way is
7954 appropriate for passing a pointer to that type.
7956 Under V.4, aggregates and long double are passed by reference.
7958 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7959 reference unless the AltiVec vector extension ABI is in force.
7961 As an extension to all ABIs, variable sized types are passed by
7965 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7966 enum machine_mode mode, const_tree type,
7967 bool named ATTRIBUTE_UNUSED)
7969 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7971 if (TARGET_DEBUG_ARG)
7972 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7979 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7981 if (TARGET_DEBUG_ARG)
7982 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7986 if (int_size_in_bytes (type) < 0)
7988 if (TARGET_DEBUG_ARG)
7989 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7993 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7994 modes only exist for GCC vector types if -maltivec. */
7995 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7997 if (TARGET_DEBUG_ARG)
7998 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8002 /* Pass synthetic vectors in memory. */
8003 if (TREE_CODE (type) == VECTOR_TYPE
8004 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8006 static bool warned_for_pass_big_vectors = false;
8007 if (TARGET_DEBUG_ARG)
8008 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8009 if (!warned_for_pass_big_vectors)
8011 warning (0, "GCC vector passed by reference: "
8012 "non-standard ABI extension with no compatibility guarantee");
8013 warned_for_pass_big_vectors = true;
8022 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8025 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8030 for (i = 0; i < nregs; i++)
8032 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8033 if (reload_completed)
8035 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8038 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8039 i * GET_MODE_SIZE (reg_mode));
8042 tem = replace_equiv_address (tem, XEXP (tem, 0));
8046 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8050 /* Perform any needed actions needed for a function that is receiving a
8051 variable number of arguments.
8055 MODE and TYPE are the mode and type of the current parameter.
8057 PRETEND_SIZE is a variable that should be set to the amount of stack
8058 that must be pushed by the prolog to pretend that our caller pushed
8061 Normally, this macro will push all remaining incoming registers on the
8062 stack and set PRETEND_SIZE to the length of the registers pushed. */
8065 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8066 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8069 CUMULATIVE_ARGS next_cum;
8070 int reg_size = TARGET_32BIT ? 4 : 8;
8071 rtx save_area = NULL_RTX, mem;
8072 int first_reg_offset;
8075 /* Skip the last named argument. */
8077 function_arg_advance (&next_cum, mode, type, 1, 0);
8079 if (DEFAULT_ABI == ABI_V4)
8081 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8085 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8086 HOST_WIDE_INT offset = 0;
8088 /* Try to optimize the size of the varargs save area.
8089 The ABI requires that ap.reg_save_area is doubleword
8090 aligned, but we don't need to allocate space for all
8091 the bytes, only those to which we actually will save
8093 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8094 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8095 if (TARGET_HARD_FLOAT && TARGET_FPRS
8096 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8097 && cfun->va_list_fpr_size)
8100 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8101 * UNITS_PER_FP_WORD;
8102 if (cfun->va_list_fpr_size
8103 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8104 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8106 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8107 * UNITS_PER_FP_WORD;
8111 offset = -((first_reg_offset * reg_size) & ~7);
8112 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8114 gpr_reg_num = cfun->va_list_gpr_size;
8115 if (reg_size == 4 && (first_reg_offset & 1))
8118 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8121 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8123 - (int) (GP_ARG_NUM_REG * reg_size);
8125 if (gpr_size + fpr_size)
8128 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8129 gcc_assert (GET_CODE (reg_save_area) == MEM);
8130 reg_save_area = XEXP (reg_save_area, 0);
8131 if (GET_CODE (reg_save_area) == PLUS)
8133 gcc_assert (XEXP (reg_save_area, 0)
8134 == virtual_stack_vars_rtx);
8135 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8136 offset += INTVAL (XEXP (reg_save_area, 1));
8139 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8142 cfun->machine->varargs_save_offset = offset;
8143 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8148 first_reg_offset = next_cum.words;
8149 save_area = virtual_incoming_args_rtx;
8151 if (targetm.calls.must_pass_in_stack (mode, type))
8152 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8155 set = get_varargs_alias_set ();
8156 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8157 && cfun->va_list_gpr_size)
8159 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8161 if (va_list_gpr_counter_field)
8163 /* V4 va_list_gpr_size counts number of registers needed. */
8164 if (nregs > cfun->va_list_gpr_size)
8165 nregs = cfun->va_list_gpr_size;
8169 /* char * va_list instead counts number of bytes needed. */
8170 if (nregs > cfun->va_list_gpr_size / reg_size)
8171 nregs = cfun->va_list_gpr_size / reg_size;
8174 mem = gen_rtx_MEM (BLKmode,
8175 plus_constant (save_area,
8176 first_reg_offset * reg_size));
8177 MEM_NOTRAP_P (mem) = 1;
8178 set_mem_alias_set (mem, set);
8179 set_mem_align (mem, BITS_PER_WORD);
8181 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8185 /* Save FP registers if needed. */
8186 if (DEFAULT_ABI == ABI_V4
8187 && TARGET_HARD_FLOAT && TARGET_FPRS
8189 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8190 && cfun->va_list_fpr_size)
8192 int fregno = next_cum.fregno, nregs;
8193 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8194 rtx lab = gen_label_rtx ();
8195 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8196 * UNITS_PER_FP_WORD);
8199 (gen_rtx_SET (VOIDmode,
8201 gen_rtx_IF_THEN_ELSE (VOIDmode,
8202 gen_rtx_NE (VOIDmode, cr1,
8204 gen_rtx_LABEL_REF (VOIDmode, lab),
8208 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8209 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8211 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8213 plus_constant (save_area, off));
8214 MEM_NOTRAP_P (mem) = 1;
8215 set_mem_alias_set (mem, set);
8216 set_mem_align (mem, GET_MODE_ALIGNMENT (
8217 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8218 ? DFmode : SFmode));
8219 emit_move_insn (mem, gen_rtx_REG (
8220 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8221 ? DFmode : SFmode, fregno));
8228 /* Create the va_list data type. */
8231 rs6000_build_builtin_va_list (void)
8233 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8235 /* For AIX, prefer 'char *' because that's what the system
8236 header files like. */
8237 if (DEFAULT_ABI != ABI_V4)
8238 return build_pointer_type (char_type_node);
8240 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8241 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8242 get_identifier ("__va_list_tag"), record);
8244 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8245 unsigned_char_type_node);
8246 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8247 unsigned_char_type_node);
8248 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8250 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8251 get_identifier ("reserved"), short_unsigned_type_node);
8252 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8253 get_identifier ("overflow_arg_area"),
8255 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8256 get_identifier ("reg_save_area"),
8259 va_list_gpr_counter_field = f_gpr;
8260 va_list_fpr_counter_field = f_fpr;
8262 DECL_FIELD_CONTEXT (f_gpr) = record;
8263 DECL_FIELD_CONTEXT (f_fpr) = record;
8264 DECL_FIELD_CONTEXT (f_res) = record;
8265 DECL_FIELD_CONTEXT (f_ovf) = record;
8266 DECL_FIELD_CONTEXT (f_sav) = record;
8268 TREE_CHAIN (record) = type_decl;
8269 TYPE_NAME (record) = type_decl;
8270 TYPE_FIELDS (record) = f_gpr;
8271 TREE_CHAIN (f_gpr) = f_fpr;
8272 TREE_CHAIN (f_fpr) = f_res;
8273 TREE_CHAIN (f_res) = f_ovf;
8274 TREE_CHAIN (f_ovf) = f_sav;
8276 layout_type (record);
8278 /* The correct type is an array type of one element. */
8279 return build_array_type (record, build_index_type (size_zero_node));
8282 /* Implement va_start. */
8285 rs6000_va_start (tree valist, rtx nextarg)
8287 HOST_WIDE_INT words, n_gpr, n_fpr;
8288 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8289 tree gpr, fpr, ovf, sav, t;
8291 /* Only SVR4 needs something special. */
8292 if (DEFAULT_ABI != ABI_V4)
8294 std_expand_builtin_va_start (valist, nextarg);
8298 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8299 f_fpr = TREE_CHAIN (f_gpr);
8300 f_res = TREE_CHAIN (f_fpr);
8301 f_ovf = TREE_CHAIN (f_res);
8302 f_sav = TREE_CHAIN (f_ovf);
8304 valist = build_va_arg_indirect_ref (valist);
8305 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8306 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8308 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8310 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8313 /* Count number of gp and fp argument registers used. */
8314 words = crtl->args.info.words;
8315 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8317 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8320 if (TARGET_DEBUG_ARG)
8321 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8322 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8323 words, n_gpr, n_fpr);
8325 if (cfun->va_list_gpr_size)
8327 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8328 build_int_cst (NULL_TREE, n_gpr));
8329 TREE_SIDE_EFFECTS (t) = 1;
8330 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8333 if (cfun->va_list_fpr_size)
8335 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8336 build_int_cst (NULL_TREE, n_fpr));
8337 TREE_SIDE_EFFECTS (t) = 1;
8338 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8341 /* Find the overflow area. */
8342 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8344 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8345 size_int (words * UNITS_PER_WORD));
8346 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8347 TREE_SIDE_EFFECTS (t) = 1;
8348 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8350 /* If there were no va_arg invocations, don't set up the register
8352 if (!cfun->va_list_gpr_size
8353 && !cfun->va_list_fpr_size
8354 && n_gpr < GP_ARG_NUM_REG
8355 && n_fpr < FP_ARG_V4_MAX_REG)
8358 /* Find the register save area. */
8359 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8360 if (cfun->machine->varargs_save_offset)
8361 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8362 size_int (cfun->machine->varargs_save_offset));
8363 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8364 TREE_SIDE_EFFECTS (t) = 1;
8365 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8368 /* Implement va_arg. */
8371 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8374 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8375 tree gpr, fpr, ovf, sav, reg, t, u;
8376 int size, rsize, n_reg, sav_ofs, sav_scale;
8377 tree lab_false, lab_over, addr;
8379 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8383 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8385 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8386 return build_va_arg_indirect_ref (t);
8389 if (DEFAULT_ABI != ABI_V4)
8391 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8393 tree elem_type = TREE_TYPE (type);
8394 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8395 int elem_size = GET_MODE_SIZE (elem_mode);
8397 if (elem_size < UNITS_PER_WORD)
8399 tree real_part, imag_part;
8400 gimple_seq post = NULL;
8402 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8404 /* Copy the value into a temporary, lest the formal temporary
8405 be reused out from under us. */
8406 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8407 gimple_seq_add_seq (pre_p, post);
8409 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8412 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8416 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8419 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8420 f_fpr = TREE_CHAIN (f_gpr);
8421 f_res = TREE_CHAIN (f_fpr);
8422 f_ovf = TREE_CHAIN (f_res);
8423 f_sav = TREE_CHAIN (f_ovf);
8425 valist = build_va_arg_indirect_ref (valist);
8426 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8427 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8429 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8431 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8434 size = int_size_in_bytes (type);
8435 rsize = (size + 3) / 4;
8438 if (TARGET_HARD_FLOAT && TARGET_FPRS
8439 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8440 || (TARGET_DOUBLE_FLOAT
8441 && (TYPE_MODE (type) == DFmode
8442 || TYPE_MODE (type) == TFmode
8443 || TYPE_MODE (type) == SDmode
8444 || TYPE_MODE (type) == DDmode
8445 || TYPE_MODE (type) == TDmode))))
8447 /* FP args go in FP registers, if present. */
8449 n_reg = (size + 7) / 8;
8450 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8451 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8452 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8457 /* Otherwise into GP registers. */
8466 /* Pull the value out of the saved registers.... */
8469 addr = create_tmp_var (ptr_type_node, "addr");
8471 /* AltiVec vectors never go in registers when -mabi=altivec. */
8472 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8476 lab_false = create_artificial_label (input_location);
8477 lab_over = create_artificial_label (input_location);
8479 /* Long long and SPE vectors are aligned in the registers.
8480 As are any other 2 gpr item such as complex int due to a
8481 historical mistake. */
8483 if (n_reg == 2 && reg == gpr)
8486 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8487 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8488 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8489 unshare_expr (reg), u);
8491 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8492 reg number is 0 for f1, so we want to make it odd. */
8493 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8495 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8496 build_int_cst (TREE_TYPE (reg), 1));
8497 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8500 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8501 t = build2 (GE_EXPR, boolean_type_node, u, t);
8502 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8503 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8504 gimplify_and_add (t, pre_p);
8508 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8510 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8511 build_int_cst (TREE_TYPE (reg), n_reg));
8512 u = fold_convert (sizetype, u);
8513 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8514 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8516 /* _Decimal32 varargs are located in the second word of the 64-bit
8517 FP register for 32-bit binaries. */
8518 if (!TARGET_POWERPC64
8519 && TARGET_HARD_FLOAT && TARGET_FPRS
8520 && TYPE_MODE (type) == SDmode)
8521 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8523 gimplify_assign (addr, t, pre_p);
8525 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8527 stmt = gimple_build_label (lab_false);
8528 gimple_seq_add_stmt (pre_p, stmt);
8530 if ((n_reg == 2 && !regalign) || n_reg > 2)
8532 /* Ensure that we don't find any more args in regs.
8533 Alignment has taken care of for special cases. */
8534 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8538 /* ... otherwise out of the overflow area. */
8540 /* Care for on-stack alignment if needed. */
8544 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8545 t = fold_convert (sizetype, t);
8546 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8548 t = fold_convert (TREE_TYPE (ovf), t);
8550 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8552 gimplify_assign (unshare_expr (addr), t, pre_p);
8554 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8555 gimplify_assign (unshare_expr (ovf), t, pre_p);
8559 stmt = gimple_build_label (lab_over);
8560 gimple_seq_add_stmt (pre_p, stmt);
8563 if (STRICT_ALIGNMENT
8564 && (TYPE_ALIGN (type)
8565 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8567 /* The value (of type complex double, for example) may not be
8568 aligned in memory in the saved registers, so copy via a
8569 temporary. (This is the same code as used for SPARC.) */
8570 tree tmp = create_tmp_var (type, "va_arg_tmp");
8571 tree dest_addr = build_fold_addr_expr (tmp);
8573 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8574 3, dest_addr, addr, size_int (rsize * 4));
8576 gimplify_and_add (copy, pre_p);
8580 addr = fold_convert (ptrtype, addr);
8581 return build_va_arg_indirect_ref (addr);
8587 def_builtin (int mask, const char *name, tree type, int code)
8589 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8592 if (rs6000_builtin_decls[code])
8593 fatal_error ("internal error: builtin function to %s already processed.",
8596 rs6000_builtin_decls[code] = t =
8597 add_builtin_function (name, type, code, BUILT_IN_MD,
8600 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8601 switch (builtin_classify[code])
8606 /* assume builtin can do anything. */
8607 case RS6000_BTC_MISC:
8610 /* const function, function only depends on the inputs. */
8611 case RS6000_BTC_CONST:
8612 TREE_READONLY (t) = 1;
8613 TREE_NOTHROW (t) = 1;
8616 /* pure function, function can read global memory. */
8617 case RS6000_BTC_PURE:
8618 DECL_PURE_P (t) = 1;
8619 TREE_NOTHROW (t) = 1;
8622 /* Function is a math function. If rounding mode is on, then treat
8623 the function as not reading global memory, but it can have
8624 arbitrary side effects. If it is off, then assume the function is
8625 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8626 attribute in builtin-attribute.def that is used for the math
8628 case RS6000_BTC_FP_PURE:
8629 TREE_NOTHROW (t) = 1;
8630 if (flag_rounding_math)
8632 DECL_PURE_P (t) = 1;
8633 DECL_IS_NOVOPS (t) = 1;
8636 TREE_READONLY (t) = 1;
8642 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8644 static const struct builtin_description bdesc_3arg[] =
8646 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8647 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8648 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8649 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8650 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8667 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8668 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8669 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8670 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8671 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8672 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8673 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8674 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8675 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8676 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8677 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8678 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8682 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8683 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8684 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8692 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8693 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8698 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8699 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8700 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8701 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8703 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8704 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8705 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8706 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8709 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8711 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8712 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8713 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8714 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8715 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8716 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8717 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8718 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8719 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8720 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8722 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8723 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8724 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8725 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8726 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8727 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8728 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8729 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8730 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8731 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8733 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8734 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8735 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8736 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8737 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8738 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8739 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8740 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8741 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8743 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8744 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8745 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8746 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8747 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8748 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8749 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8751 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8752 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8753 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8754 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8755 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8756 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8757 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8758 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8759 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8762 /* DST operations: void foo (void *, const int, const char). */
8764 static const struct builtin_description bdesc_dst[] =
8766 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8767 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8768 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8769 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8777 /* Simple binary operations: VECc = foo (VECa, VECb). */
8779 static struct builtin_description bdesc_2arg[] =
8781 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8782 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8783 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8784 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8785 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8786 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8787 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8788 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8789 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8790 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8791 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8792 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8793 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8794 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8795 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8796 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8797 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8798 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8799 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8800 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8803 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8804 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8805 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8806 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8807 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8808 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8809 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8810 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8811 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8812 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8813 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8814 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8815 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8816 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8817 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8818 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8819 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8820 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8821 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8822 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8823 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8824 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8825 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8826 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8827 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8828 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8829 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8830 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8831 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8832 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8833 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8834 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8835 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8836 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8837 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8838 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8839 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8840 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8841 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8846 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8847 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8848 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8849 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8850 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8851 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8852 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8854 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8855 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8860 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8861 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8862 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8863 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8864 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8865 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8866 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8867 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8868 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8869 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8870 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8871 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8872 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8873 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8874 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8875 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8876 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8877 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8878 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8879 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8880 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8881 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8882 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8883 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8884 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8885 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8886 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8887 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8888 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8889 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8890 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8891 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8892 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8895 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8896 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8898 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8899 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8900 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8901 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8902 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8903 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8904 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8905 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8906 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8907 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8908 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8910 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8911 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8912 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8913 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8914 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8915 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8916 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8917 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8918 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8919 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8920 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8922 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8923 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8924 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8925 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8926 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8927 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8929 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8930 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8931 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8932 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8933 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8934 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8935 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8936 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8937 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8938 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8939 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8940 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8942 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8943 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8955 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8956 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8982 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8983 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8998 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8999 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9016 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9017 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9050 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9051 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9069 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9071 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9072 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9074 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9075 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9076 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9077 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9078 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9079 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9080 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9081 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9082 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9083 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9085 /* Place holder, leave as first spe builtin. */
9086 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9087 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9088 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9089 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9090 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9091 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9092 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9093 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9094 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9095 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9096 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9097 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9098 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9099 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9100 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9101 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9102 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9103 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9104 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9105 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9106 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9107 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9108 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9109 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9110 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9111 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9112 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9113 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9114 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9115 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9116 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9117 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9118 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9119 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9120 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9121 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9122 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9123 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9124 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9125 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9126 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9127 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9128 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9129 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9130 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9131 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9132 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9133 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9134 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9135 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9136 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9137 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9138 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9139 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9140 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9141 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9142 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9143 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9144 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9145 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9146 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9147 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9148 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9149 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9150 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9151 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9152 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9153 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9154 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9155 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9156 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9157 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9158 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9159 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9160 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9161 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9162 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9163 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9164 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9165 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9166 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9167 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9168 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9169 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9170 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9171 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9172 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9173 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9174 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9175 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9176 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9177 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9178 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9179 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9180 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9181 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9182 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9183 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9184 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9185 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9186 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9187 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9188 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9189 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9190 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9191 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9192 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9193 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9194 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9196 /* SPE binary operations expecting a 5-bit unsigned literal. */
9197 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9199 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9200 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9201 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9202 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9203 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9204 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9205 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9206 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9207 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9208 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9209 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9210 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9211 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9212 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9213 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9214 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9215 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9216 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9217 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9218 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9219 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9220 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9221 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9222 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9223 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9224 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9226 /* Place-holder. Leave as last binary SPE builtin. */
9227 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9230 /* AltiVec predicates. */
9232 struct builtin_description_predicates
9234 const unsigned int mask;
9235 const enum insn_code icode;
9236 const char *const name;
9237 const enum rs6000_builtins code;
9240 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9242 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9243 ALTIVEC_BUILTIN_VCMPBFP_P },
9244 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9245 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9246 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9247 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9248 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9249 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9250 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9251 ALTIVEC_BUILTIN_VCMPEQUW_P },
9252 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9253 ALTIVEC_BUILTIN_VCMPGTSW_P },
9254 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9255 ALTIVEC_BUILTIN_VCMPGTUW_P },
9256 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9257 ALTIVEC_BUILTIN_VCMPEQUH_P },
9258 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9259 ALTIVEC_BUILTIN_VCMPGTSH_P },
9260 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9261 ALTIVEC_BUILTIN_VCMPGTUH_P },
9262 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9263 ALTIVEC_BUILTIN_VCMPEQUB_P },
9264 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9265 ALTIVEC_BUILTIN_VCMPGTSB_P },
9266 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9267 ALTIVEC_BUILTIN_VCMPGTUB_P },
9269 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9270 VSX_BUILTIN_XVCMPEQSP_P },
9271 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9272 VSX_BUILTIN_XVCMPGESP_P },
9273 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9274 VSX_BUILTIN_XVCMPGTSP_P },
9275 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9276 VSX_BUILTIN_XVCMPEQDP_P },
9277 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9278 VSX_BUILTIN_XVCMPGEDP_P },
9279 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9280 VSX_BUILTIN_XVCMPGTDP_P },
9282 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9283 ALTIVEC_BUILTIN_VCMPEQ_P },
9284 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9285 ALTIVEC_BUILTIN_VCMPGT_P },
9286 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9287 ALTIVEC_BUILTIN_VCMPGE_P }
9290 /* SPE predicates. */
9291 static struct builtin_description bdesc_spe_predicates[] =
9293 /* Place-holder. Leave as first. */
9294 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9295 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9296 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9297 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9298 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9299 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9300 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9301 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9302 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9303 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9304 /* Place-holder. Leave as last. */
9305 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9308 /* SPE evsel predicates. */
9309 static struct builtin_description bdesc_spe_evsel[] =
9311 /* Place-holder. Leave as first. */
9312 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9313 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9314 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9315 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9316 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9317 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9318 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9319 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9320 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9321 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9322 /* Place-holder. Leave as last. */
9323 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9326 /* PAIRED predicates. */
9327 static const struct builtin_description bdesc_paired_preds[] =
9329 /* Place-holder. Leave as first. */
9330 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9331 /* Place-holder. Leave as last. */
9332 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9335 /* ABS* operations. */
9337 static const struct builtin_description bdesc_abs[] =
9339 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9340 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9341 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9342 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9343 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9344 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9345 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9346 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9347 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9348 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9349 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9352 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9355 static struct builtin_description bdesc_1arg[] =
9357 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9358 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9359 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9360 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9361 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9362 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9363 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9364 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9365 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9366 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9367 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9368 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9369 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9370 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9371 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9372 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9375 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9376 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9377 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9378 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9379 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9380 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9382 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9383 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9384 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9385 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9386 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9387 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9389 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9390 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9391 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9392 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9393 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9394 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9396 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9397 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9398 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9399 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9400 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9401 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9403 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9404 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9405 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9406 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9408 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9409 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9410 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9411 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9412 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9413 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9414 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9415 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9416 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9418 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9419 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9420 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9421 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9422 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9423 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9424 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9425 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9426 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9428 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9429 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9430 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9431 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9432 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9454 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9455 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9456 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9458 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9459 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9460 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9461 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9463 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9464 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9465 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9466 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9467 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9468 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9469 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9470 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9471 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9472 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9473 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9474 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9475 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9476 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9477 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9478 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9479 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9480 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9481 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9482 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9483 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9484 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9485 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9486 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9487 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9488 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9489 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9490 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9491 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9492 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9494 /* Place-holder. Leave as last unary SPE builtin. */
9495 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9497 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9498 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9499 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9500 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9501 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9505 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9508 tree arg0 = CALL_EXPR_ARG (exp, 0);
9509 rtx op0 = expand_normal (arg0);
9510 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9511 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9513 if (icode == CODE_FOR_nothing)
9514 /* Builtin not supported on this processor. */
9517 /* If we got invalid arguments bail out before generating bad rtl. */
9518 if (arg0 == error_mark_node)
9521 if (icode == CODE_FOR_altivec_vspltisb
9522 || icode == CODE_FOR_altivec_vspltish
9523 || icode == CODE_FOR_altivec_vspltisw
9524 || icode == CODE_FOR_spe_evsplatfi
9525 || icode == CODE_FOR_spe_evsplati)
9527 /* Only allow 5-bit *signed* literals. */
9528 if (GET_CODE (op0) != CONST_INT
9529 || INTVAL (op0) > 15
9530 || INTVAL (op0) < -16)
9532 error ("argument 1 must be a 5-bit signed literal");
9538 || GET_MODE (target) != tmode
9539 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9540 target = gen_reg_rtx (tmode);
9542 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9543 op0 = copy_to_mode_reg (mode0, op0);
9545 pat = GEN_FCN (icode) (target, op0);
9554 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9556 rtx pat, scratch1, scratch2;
9557 tree arg0 = CALL_EXPR_ARG (exp, 0);
9558 rtx op0 = expand_normal (arg0);
9559 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9560 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9562 /* If we have invalid arguments, bail out before generating bad rtl. */
9563 if (arg0 == error_mark_node)
9567 || GET_MODE (target) != tmode
9568 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9569 target = gen_reg_rtx (tmode);
9571 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9572 op0 = copy_to_mode_reg (mode0, op0);
9574 scratch1 = gen_reg_rtx (mode0);
9575 scratch2 = gen_reg_rtx (mode0);
9577 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9586 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9589 tree arg0 = CALL_EXPR_ARG (exp, 0);
9590 tree arg1 = CALL_EXPR_ARG (exp, 1);
9591 rtx op0 = expand_normal (arg0);
9592 rtx op1 = expand_normal (arg1);
9593 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9594 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9595 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9597 if (icode == CODE_FOR_nothing)
9598 /* Builtin not supported on this processor. */
9601 /* If we got invalid arguments bail out before generating bad rtl. */
9602 if (arg0 == error_mark_node || arg1 == error_mark_node)
9605 if (icode == CODE_FOR_altivec_vcfux
9606 || icode == CODE_FOR_altivec_vcfsx
9607 || icode == CODE_FOR_altivec_vctsxs
9608 || icode == CODE_FOR_altivec_vctuxs
9609 || icode == CODE_FOR_altivec_vspltb
9610 || icode == CODE_FOR_altivec_vsplth
9611 || icode == CODE_FOR_altivec_vspltw
9612 || icode == CODE_FOR_spe_evaddiw
9613 || icode == CODE_FOR_spe_evldd
9614 || icode == CODE_FOR_spe_evldh
9615 || icode == CODE_FOR_spe_evldw
9616 || icode == CODE_FOR_spe_evlhhesplat
9617 || icode == CODE_FOR_spe_evlhhossplat
9618 || icode == CODE_FOR_spe_evlhhousplat
9619 || icode == CODE_FOR_spe_evlwhe
9620 || icode == CODE_FOR_spe_evlwhos
9621 || icode == CODE_FOR_spe_evlwhou
9622 || icode == CODE_FOR_spe_evlwhsplat
9623 || icode == CODE_FOR_spe_evlwwsplat
9624 || icode == CODE_FOR_spe_evrlwi
9625 || icode == CODE_FOR_spe_evslwi
9626 || icode == CODE_FOR_spe_evsrwis
9627 || icode == CODE_FOR_spe_evsubifw
9628 || icode == CODE_FOR_spe_evsrwiu)
9630 /* Only allow 5-bit unsigned literals. */
9632 if (TREE_CODE (arg1) != INTEGER_CST
9633 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9635 error ("argument 2 must be a 5-bit unsigned literal");
9641 || GET_MODE (target) != tmode
9642 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9643 target = gen_reg_rtx (tmode);
9645 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9646 op0 = copy_to_mode_reg (mode0, op0);
9647 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9648 op1 = copy_to_mode_reg (mode1, op1);
9650 pat = GEN_FCN (icode) (target, op0, op1);
9659 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9662 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9663 tree arg0 = CALL_EXPR_ARG (exp, 1);
9664 tree arg1 = CALL_EXPR_ARG (exp, 2);
9665 rtx op0 = expand_normal (arg0);
9666 rtx op1 = expand_normal (arg1);
9667 enum machine_mode tmode = SImode;
9668 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9669 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9672 if (TREE_CODE (cr6_form) != INTEGER_CST)
9674 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9678 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9680 gcc_assert (mode0 == mode1);
9682 /* If we have invalid arguments, bail out before generating bad rtl. */
9683 if (arg0 == error_mark_node || arg1 == error_mark_node)
9687 || GET_MODE (target) != tmode
9688 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9689 target = gen_reg_rtx (tmode);
9691 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9692 op0 = copy_to_mode_reg (mode0, op0);
9693 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9694 op1 = copy_to_mode_reg (mode1, op1);
9696 scratch = gen_reg_rtx (mode0);
9698 pat = GEN_FCN (icode) (scratch, op0, op1);
9703 /* The vec_any* and vec_all* predicates use the same opcodes for two
9704 different operations, but the bits in CR6 will be different
9705 depending on what information we want. So we have to play tricks
9706 with CR6 to get the right bits out.
9708 If you think this is disgusting, look at the specs for the
9709 AltiVec predicates. */
9711 switch (cr6_form_int)
9714 emit_insn (gen_cr6_test_for_zero (target));
9717 emit_insn (gen_cr6_test_for_zero_reverse (target));
9720 emit_insn (gen_cr6_test_for_lt (target));
9723 emit_insn (gen_cr6_test_for_lt_reverse (target));
9726 error ("argument 1 of __builtin_altivec_predicate is out of range");
9734 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9737 tree arg0 = CALL_EXPR_ARG (exp, 0);
9738 tree arg1 = CALL_EXPR_ARG (exp, 1);
9739 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9740 enum machine_mode mode0 = Pmode;
9741 enum machine_mode mode1 = Pmode;
9742 rtx op0 = expand_normal (arg0);
9743 rtx op1 = expand_normal (arg1);
9745 if (icode == CODE_FOR_nothing)
9746 /* Builtin not supported on this processor. */
9749 /* If we got invalid arguments bail out before generating bad rtl. */
9750 if (arg0 == error_mark_node || arg1 == error_mark_node)
9754 || GET_MODE (target) != tmode
9755 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9756 target = gen_reg_rtx (tmode);
9758 op1 = copy_to_mode_reg (mode1, op1);
9760 if (op0 == const0_rtx)
9762 addr = gen_rtx_MEM (tmode, op1);
9766 op0 = copy_to_mode_reg (mode0, op0);
9767 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9770 pat = GEN_FCN (icode) (target, addr);
9780 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9783 tree arg0 = CALL_EXPR_ARG (exp, 0);
9784 tree arg1 = CALL_EXPR_ARG (exp, 1);
9785 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9786 enum machine_mode mode0 = Pmode;
9787 enum machine_mode mode1 = Pmode;
9788 rtx op0 = expand_normal (arg0);
9789 rtx op1 = expand_normal (arg1);
9791 if (icode == CODE_FOR_nothing)
9792 /* Builtin not supported on this processor. */
9795 /* If we got invalid arguments bail out before generating bad rtl. */
9796 if (arg0 == error_mark_node || arg1 == error_mark_node)
9800 || GET_MODE (target) != tmode
9801 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9802 target = gen_reg_rtx (tmode);
9804 op1 = copy_to_mode_reg (mode1, op1);
9806 if (op0 == const0_rtx)
9808 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9812 op0 = copy_to_mode_reg (mode0, op0);
9813 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9816 pat = GEN_FCN (icode) (target, addr);
9826 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9828 tree arg0 = CALL_EXPR_ARG (exp, 0);
9829 tree arg1 = CALL_EXPR_ARG (exp, 1);
9830 tree arg2 = CALL_EXPR_ARG (exp, 2);
9831 rtx op0 = expand_normal (arg0);
9832 rtx op1 = expand_normal (arg1);
9833 rtx op2 = expand_normal (arg2);
9835 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9836 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9837 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9839 /* Invalid arguments. Bail before doing anything stoopid! */
9840 if (arg0 == error_mark_node
9841 || arg1 == error_mark_node
9842 || arg2 == error_mark_node)
9845 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9846 op0 = copy_to_mode_reg (mode2, op0);
9847 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9848 op1 = copy_to_mode_reg (mode0, op1);
9849 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9850 op2 = copy_to_mode_reg (mode1, op2);
9852 pat = GEN_FCN (icode) (op1, op2, op0);
9859 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9861 tree arg0 = CALL_EXPR_ARG (exp, 0);
9862 tree arg1 = CALL_EXPR_ARG (exp, 1);
9863 tree arg2 = CALL_EXPR_ARG (exp, 2);
9864 rtx op0 = expand_normal (arg0);
9865 rtx op1 = expand_normal (arg1);
9866 rtx op2 = expand_normal (arg2);
9868 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9869 enum machine_mode mode1 = Pmode;
9870 enum machine_mode mode2 = Pmode;
9872 /* Invalid arguments. Bail before doing anything stoopid! */
9873 if (arg0 == error_mark_node
9874 || arg1 == error_mark_node
9875 || arg2 == error_mark_node)
9878 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9879 op0 = copy_to_mode_reg (tmode, op0);
9881 op2 = copy_to_mode_reg (mode2, op2);
9883 if (op1 == const0_rtx)
9885 addr = gen_rtx_MEM (tmode, op2);
9889 op1 = copy_to_mode_reg (mode1, op1);
9890 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9893 pat = GEN_FCN (icode) (addr, op0);
9900 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9902 tree arg0 = CALL_EXPR_ARG (exp, 0);
9903 tree arg1 = CALL_EXPR_ARG (exp, 1);
9904 tree arg2 = CALL_EXPR_ARG (exp, 2);
9905 rtx op0 = expand_normal (arg0);
9906 rtx op1 = expand_normal (arg1);
9907 rtx op2 = expand_normal (arg2);
9909 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9910 enum machine_mode mode1 = Pmode;
9911 enum machine_mode mode2 = Pmode;
9913 /* Invalid arguments. Bail before doing anything stoopid! */
9914 if (arg0 == error_mark_node
9915 || arg1 == error_mark_node
9916 || arg2 == error_mark_node)
9919 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9920 op0 = copy_to_mode_reg (tmode, op0);
9922 op2 = copy_to_mode_reg (mode2, op2);
9924 if (op1 == const0_rtx)
9926 addr = gen_rtx_MEM (tmode, op2);
9930 op1 = copy_to_mode_reg (mode1, op1);
9931 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9934 pat = GEN_FCN (icode) (addr, op0);
9941 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9944 tree arg0 = CALL_EXPR_ARG (exp, 0);
9945 tree arg1 = CALL_EXPR_ARG (exp, 1);
9946 tree arg2 = CALL_EXPR_ARG (exp, 2);
9947 rtx op0 = expand_normal (arg0);
9948 rtx op1 = expand_normal (arg1);
9949 rtx op2 = expand_normal (arg2);
9950 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9951 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9952 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9953 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9955 if (icode == CODE_FOR_nothing)
9956 /* Builtin not supported on this processor. */
9959 /* If we got invalid arguments bail out before generating bad rtl. */
9960 if (arg0 == error_mark_node
9961 || arg1 == error_mark_node
9962 || arg2 == error_mark_node)
9967 case CODE_FOR_altivec_vsldoi_v4sf:
9968 case CODE_FOR_altivec_vsldoi_v4si:
9969 case CODE_FOR_altivec_vsldoi_v8hi:
9970 case CODE_FOR_altivec_vsldoi_v16qi:
9971 /* Only allow 4-bit unsigned literals. */
9973 if (TREE_CODE (arg2) != INTEGER_CST
9974 || TREE_INT_CST_LOW (arg2) & ~0xf)
9976 error ("argument 3 must be a 4-bit unsigned literal");
9981 case CODE_FOR_vsx_xxpermdi_v2df:
9982 case CODE_FOR_vsx_xxpermdi_v2di:
9983 case CODE_FOR_vsx_xxsldwi_v16qi:
9984 case CODE_FOR_vsx_xxsldwi_v8hi:
9985 case CODE_FOR_vsx_xxsldwi_v4si:
9986 case CODE_FOR_vsx_xxsldwi_v4sf:
9987 case CODE_FOR_vsx_xxsldwi_v2di:
9988 case CODE_FOR_vsx_xxsldwi_v2df:
9989 /* Only allow 2-bit unsigned literals. */
9991 if (TREE_CODE (arg2) != INTEGER_CST
9992 || TREE_INT_CST_LOW (arg2) & ~0x3)
9994 error ("argument 3 must be a 2-bit unsigned literal");
9999 case CODE_FOR_vsx_set_v2df:
10000 case CODE_FOR_vsx_set_v2di:
10001 /* Only allow 1-bit unsigned literals. */
10003 if (TREE_CODE (arg2) != INTEGER_CST
10004 || TREE_INT_CST_LOW (arg2) & ~0x1)
10006 error ("argument 3 must be a 1-bit unsigned literal");
10016 || GET_MODE (target) != tmode
10017 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10018 target = gen_reg_rtx (tmode);
10020 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10021 op0 = copy_to_mode_reg (mode0, op0);
10022 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10023 op1 = copy_to_mode_reg (mode1, op1);
10024 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10025 op2 = copy_to_mode_reg (mode2, op2);
10027 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10028 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10030 pat = GEN_FCN (icode) (target, op0, op1, op2);
10038 /* Expand the lvx builtins. */
10040 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10042 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10043 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10045 enum machine_mode tmode, mode0;
10047 enum insn_code icode;
10051 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10052 icode = CODE_FOR_vector_load_v16qi;
10054 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10055 icode = CODE_FOR_vector_load_v8hi;
10057 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10058 icode = CODE_FOR_vector_load_v4si;
10060 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10061 icode = CODE_FOR_vector_load_v4sf;
10064 *expandedp = false;
10070 arg0 = CALL_EXPR_ARG (exp, 0);
10071 op0 = expand_normal (arg0);
10072 tmode = insn_data[icode].operand[0].mode;
10073 mode0 = insn_data[icode].operand[1].mode;
10076 || GET_MODE (target) != tmode
10077 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10078 target = gen_reg_rtx (tmode);
10080 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10081 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10083 pat = GEN_FCN (icode) (target, op0);
10090 /* Expand the stvx builtins. */
10092 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10095 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10096 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10098 enum machine_mode mode0, mode1;
10100 enum insn_code icode;
10104 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10105 icode = CODE_FOR_vector_store_v16qi;
10107 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10108 icode = CODE_FOR_vector_store_v8hi;
10110 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10111 icode = CODE_FOR_vector_store_v4si;
10113 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10114 icode = CODE_FOR_vector_store_v4sf;
10117 *expandedp = false;
10121 arg0 = CALL_EXPR_ARG (exp, 0);
10122 arg1 = CALL_EXPR_ARG (exp, 1);
10123 op0 = expand_normal (arg0);
10124 op1 = expand_normal (arg1);
10125 mode0 = insn_data[icode].operand[0].mode;
10126 mode1 = insn_data[icode].operand[1].mode;
10128 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10129 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10130 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10131 op1 = copy_to_mode_reg (mode1, op1);
10133 pat = GEN_FCN (icode) (op0, op1);
10141 /* Expand the dst builtins. */
10143 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10146 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10147 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10148 tree arg0, arg1, arg2;
10149 enum machine_mode mode0, mode1, mode2;
10150 rtx pat, op0, op1, op2;
10151 const struct builtin_description *d;
10154 *expandedp = false;
10156 /* Handle DST variants. */
10158 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10159 if (d->code == fcode)
10161 arg0 = CALL_EXPR_ARG (exp, 0);
10162 arg1 = CALL_EXPR_ARG (exp, 1);
10163 arg2 = CALL_EXPR_ARG (exp, 2);
10164 op0 = expand_normal (arg0);
10165 op1 = expand_normal (arg1);
10166 op2 = expand_normal (arg2);
10167 mode0 = insn_data[d->icode].operand[0].mode;
10168 mode1 = insn_data[d->icode].operand[1].mode;
10169 mode2 = insn_data[d->icode].operand[2].mode;
10171 /* Invalid arguments, bail out before generating bad rtl. */
10172 if (arg0 == error_mark_node
10173 || arg1 == error_mark_node
10174 || arg2 == error_mark_node)
10179 if (TREE_CODE (arg2) != INTEGER_CST
10180 || TREE_INT_CST_LOW (arg2) & ~0x3)
10182 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10186 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10187 op0 = copy_to_mode_reg (Pmode, op0);
10188 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10189 op1 = copy_to_mode_reg (mode1, op1);
10191 pat = GEN_FCN (d->icode) (op0, op1, op2);
10201 /* Expand vec_init builtin. */
10203 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10205 enum machine_mode tmode = TYPE_MODE (type);
10206 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10207 int i, n_elt = GET_MODE_NUNITS (tmode);
10208 rtvec v = rtvec_alloc (n_elt);
10210 gcc_assert (VECTOR_MODE_P (tmode));
10211 gcc_assert (n_elt == call_expr_nargs (exp));
10213 for (i = 0; i < n_elt; ++i)
10215 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10216 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10219 if (!target || !register_operand (target, tmode))
10220 target = gen_reg_rtx (tmode);
10222 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10226 /* Return the integer constant in ARG. Constrain it to be in the range
10227 of the subparts of VEC_TYPE; issue an error if not. */
10230 get_element_number (tree vec_type, tree arg)
10232 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10234 if (!host_integerp (arg, 1)
10235 || (elt = tree_low_cst (arg, 1), elt > max))
10237 error ("selector must be an integer constant in the range 0..%wi", max);
10244 /* Expand vec_set builtin. */
10246 altivec_expand_vec_set_builtin (tree exp)
10248 enum machine_mode tmode, mode1;
10249 tree arg0, arg1, arg2;
10253 arg0 = CALL_EXPR_ARG (exp, 0);
10254 arg1 = CALL_EXPR_ARG (exp, 1);
10255 arg2 = CALL_EXPR_ARG (exp, 2);
10257 tmode = TYPE_MODE (TREE_TYPE (arg0));
10258 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10259 gcc_assert (VECTOR_MODE_P (tmode));
10261 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10262 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10263 elt = get_element_number (TREE_TYPE (arg0), arg2);
10265 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10266 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10268 op0 = force_reg (tmode, op0);
10269 op1 = force_reg (mode1, op1);
10271 rs6000_expand_vector_set (op0, op1, elt);
10276 /* Expand vec_ext builtin. */
10278 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10280 enum machine_mode tmode, mode0;
10285 arg0 = CALL_EXPR_ARG (exp, 0);
10286 arg1 = CALL_EXPR_ARG (exp, 1);
10288 op0 = expand_normal (arg0);
10289 elt = get_element_number (TREE_TYPE (arg0), arg1);
10291 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10292 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10293 gcc_assert (VECTOR_MODE_P (mode0));
10295 op0 = force_reg (mode0, op0);
10297 if (optimize || !target || !register_operand (target, tmode))
10298 target = gen_reg_rtx (tmode);
10300 rs6000_expand_vector_extract (target, op0, elt);
10305 /* Expand the builtin in EXP and store the result in TARGET. Store
10306 true in *EXPANDEDP if we found a builtin to expand. */
10308 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10310 const struct builtin_description *d;
10311 const struct builtin_description_predicates *dp;
10313 enum insn_code icode;
10314 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10317 enum machine_mode tmode, mode0;
10318 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10320 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10321 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10322 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10323 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10326 error ("unresolved overload for Altivec builtin %qF", fndecl);
10330 target = altivec_expand_ld_builtin (exp, target, expandedp);
10334 target = altivec_expand_st_builtin (exp, target, expandedp);
10338 target = altivec_expand_dst_builtin (exp, target, expandedp);
10346 case ALTIVEC_BUILTIN_STVX:
10347 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10348 case ALTIVEC_BUILTIN_STVEBX:
10349 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10350 case ALTIVEC_BUILTIN_STVEHX:
10351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10352 case ALTIVEC_BUILTIN_STVEWX:
10353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10354 case ALTIVEC_BUILTIN_STVXL:
10355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10357 case ALTIVEC_BUILTIN_STVLX:
10358 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10359 case ALTIVEC_BUILTIN_STVLXL:
10360 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10361 case ALTIVEC_BUILTIN_STVRX:
10362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10363 case ALTIVEC_BUILTIN_STVRXL:
10364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10366 case ALTIVEC_BUILTIN_MFVSCR:
10367 icode = CODE_FOR_altivec_mfvscr;
10368 tmode = insn_data[icode].operand[0].mode;
10371 || GET_MODE (target) != tmode
10372 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10373 target = gen_reg_rtx (tmode);
10375 pat = GEN_FCN (icode) (target);
10381 case ALTIVEC_BUILTIN_MTVSCR:
10382 icode = CODE_FOR_altivec_mtvscr;
10383 arg0 = CALL_EXPR_ARG (exp, 0);
10384 op0 = expand_normal (arg0);
10385 mode0 = insn_data[icode].operand[0].mode;
10387 /* If we got invalid arguments bail out before generating bad rtl. */
10388 if (arg0 == error_mark_node)
10391 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10392 op0 = copy_to_mode_reg (mode0, op0);
10394 pat = GEN_FCN (icode) (op0);
10399 case ALTIVEC_BUILTIN_DSSALL:
10400 emit_insn (gen_altivec_dssall ());
10403 case ALTIVEC_BUILTIN_DSS:
10404 icode = CODE_FOR_altivec_dss;
10405 arg0 = CALL_EXPR_ARG (exp, 0);
10407 op0 = expand_normal (arg0);
10408 mode0 = insn_data[icode].operand[0].mode;
10410 /* If we got invalid arguments bail out before generating bad rtl. */
10411 if (arg0 == error_mark_node)
10414 if (TREE_CODE (arg0) != INTEGER_CST
10415 || TREE_INT_CST_LOW (arg0) & ~0x3)
10417 error ("argument to dss must be a 2-bit unsigned literal");
10421 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10422 op0 = copy_to_mode_reg (mode0, op0);
10424 emit_insn (gen_altivec_dss (op0));
10427 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10428 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10429 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10430 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10431 case VSX_BUILTIN_VEC_INIT_V2DF:
10432 case VSX_BUILTIN_VEC_INIT_V2DI:
10433 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10435 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10436 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10437 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10438 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10439 case VSX_BUILTIN_VEC_SET_V2DF:
10440 case VSX_BUILTIN_VEC_SET_V2DI:
10441 return altivec_expand_vec_set_builtin (exp);
10443 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10444 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10445 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10446 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10447 case VSX_BUILTIN_VEC_EXT_V2DF:
10448 case VSX_BUILTIN_VEC_EXT_V2DI:
10449 return altivec_expand_vec_ext_builtin (exp, target);
10453 /* Fall through. */
10456 /* Expand abs* operations. */
10458 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10459 if (d->code == fcode)
10460 return altivec_expand_abs_builtin (d->icode, exp, target);
10462 /* Expand the AltiVec predicates. */
10463 dp = bdesc_altivec_preds;
10464 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10465 if (dp->code == fcode)
10466 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10468 /* LV* are funky. We initialized them differently. */
10471 case ALTIVEC_BUILTIN_LVSL:
10472 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10473 exp, target, false);
10474 case ALTIVEC_BUILTIN_LVSR:
10475 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10476 exp, target, false);
10477 case ALTIVEC_BUILTIN_LVEBX:
10478 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10479 exp, target, false);
10480 case ALTIVEC_BUILTIN_LVEHX:
10481 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10482 exp, target, false);
10483 case ALTIVEC_BUILTIN_LVEWX:
10484 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10485 exp, target, false);
10486 case ALTIVEC_BUILTIN_LVXL:
10487 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10488 exp, target, false);
10489 case ALTIVEC_BUILTIN_LVX:
10490 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10491 exp, target, false);
10492 case ALTIVEC_BUILTIN_LVLX:
10493 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10494 exp, target, true);
10495 case ALTIVEC_BUILTIN_LVLXL:
10496 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10497 exp, target, true);
10498 case ALTIVEC_BUILTIN_LVRX:
10499 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10500 exp, target, true);
10501 case ALTIVEC_BUILTIN_LVRXL:
10502 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10503 exp, target, true);
10506 /* Fall through. */
10509 *expandedp = false;
10513 /* Expand the builtin in EXP and store the result in TARGET. Store
10514 true in *EXPANDEDP if we found a builtin to expand. */
10516 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10518 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10519 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10520 const struct builtin_description *d;
10527 case PAIRED_BUILTIN_STX:
10528 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10529 case PAIRED_BUILTIN_LX:
10530 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10533 /* Fall through. */
10536 /* Expand the paired predicates. */
10537 d = bdesc_paired_preds;
10538 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10539 if (d->code == fcode)
10540 return paired_expand_predicate_builtin (d->icode, exp, target);
10542 *expandedp = false;
10546 /* Binops that need to be initialized manually, but can be expanded
10547 automagically by rs6000_expand_binop_builtin. */
10548 static struct builtin_description bdesc_2arg_spe[] =
10550 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10551 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10552 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10553 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10554 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10555 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10556 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10557 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10558 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10559 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10560 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10561 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10562 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10563 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10564 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10565 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10566 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10567 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10568 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10569 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10570 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10571 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10574 /* Expand the builtin in EXP and store the result in TARGET. Store
10575 true in *EXPANDEDP if we found a builtin to expand.
10577 This expands the SPE builtins that are not simple unary and binary
10580 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10582 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10584 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10585 enum insn_code icode;
10586 enum machine_mode tmode, mode0;
10588 struct builtin_description *d;
10593 /* Syntax check for a 5-bit unsigned immediate. */
10596 case SPE_BUILTIN_EVSTDD:
10597 case SPE_BUILTIN_EVSTDH:
10598 case SPE_BUILTIN_EVSTDW:
10599 case SPE_BUILTIN_EVSTWHE:
10600 case SPE_BUILTIN_EVSTWHO:
10601 case SPE_BUILTIN_EVSTWWE:
10602 case SPE_BUILTIN_EVSTWWO:
10603 arg1 = CALL_EXPR_ARG (exp, 2);
10604 if (TREE_CODE (arg1) != INTEGER_CST
10605 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10607 error ("argument 2 must be a 5-bit unsigned literal");
10615 /* The evsplat*i instructions are not quite generic. */
10618 case SPE_BUILTIN_EVSPLATFI:
10619 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10621 case SPE_BUILTIN_EVSPLATI:
10622 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10628 d = (struct builtin_description *) bdesc_2arg_spe;
10629 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10630 if (d->code == fcode)
10631 return rs6000_expand_binop_builtin (d->icode, exp, target);
10633 d = (struct builtin_description *) bdesc_spe_predicates;
10634 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10635 if (d->code == fcode)
10636 return spe_expand_predicate_builtin (d->icode, exp, target);
10638 d = (struct builtin_description *) bdesc_spe_evsel;
10639 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10640 if (d->code == fcode)
10641 return spe_expand_evsel_builtin (d->icode, exp, target);
10645 case SPE_BUILTIN_EVSTDDX:
10646 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10647 case SPE_BUILTIN_EVSTDHX:
10648 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10649 case SPE_BUILTIN_EVSTDWX:
10650 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10651 case SPE_BUILTIN_EVSTWHEX:
10652 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10653 case SPE_BUILTIN_EVSTWHOX:
10654 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10655 case SPE_BUILTIN_EVSTWWEX:
10656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10657 case SPE_BUILTIN_EVSTWWOX:
10658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10659 case SPE_BUILTIN_EVSTDD:
10660 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10661 case SPE_BUILTIN_EVSTDH:
10662 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10663 case SPE_BUILTIN_EVSTDW:
10664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10665 case SPE_BUILTIN_EVSTWHE:
10666 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10667 case SPE_BUILTIN_EVSTWHO:
10668 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10669 case SPE_BUILTIN_EVSTWWE:
10670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10671 case SPE_BUILTIN_EVSTWWO:
10672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10673 case SPE_BUILTIN_MFSPEFSCR:
10674 icode = CODE_FOR_spe_mfspefscr;
10675 tmode = insn_data[icode].operand[0].mode;
10678 || GET_MODE (target) != tmode
10679 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10680 target = gen_reg_rtx (tmode);
10682 pat = GEN_FCN (icode) (target);
10687 case SPE_BUILTIN_MTSPEFSCR:
10688 icode = CODE_FOR_spe_mtspefscr;
10689 arg0 = CALL_EXPR_ARG (exp, 0);
10690 op0 = expand_normal (arg0);
10691 mode0 = insn_data[icode].operand[0].mode;
10693 if (arg0 == error_mark_node)
10696 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10697 op0 = copy_to_mode_reg (mode0, op0);
10699 pat = GEN_FCN (icode) (op0);
10707 *expandedp = false;
10712 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10714 rtx pat, scratch, tmp;
10715 tree form = CALL_EXPR_ARG (exp, 0);
10716 tree arg0 = CALL_EXPR_ARG (exp, 1);
10717 tree arg1 = CALL_EXPR_ARG (exp, 2);
10718 rtx op0 = expand_normal (arg0);
10719 rtx op1 = expand_normal (arg1);
10720 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10721 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10723 enum rtx_code code;
10725 if (TREE_CODE (form) != INTEGER_CST)
10727 error ("argument 1 of __builtin_paired_predicate must be a constant");
10731 form_int = TREE_INT_CST_LOW (form);
10733 gcc_assert (mode0 == mode1);
10735 if (arg0 == error_mark_node || arg1 == error_mark_node)
10739 || GET_MODE (target) != SImode
10740 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10741 target = gen_reg_rtx (SImode);
10742 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10743 op0 = copy_to_mode_reg (mode0, op0);
10744 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10745 op1 = copy_to_mode_reg (mode1, op1);
10747 scratch = gen_reg_rtx (CCFPmode);
10749 pat = GEN_FCN (icode) (scratch, op0, op1);
10771 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10774 error ("argument 1 of __builtin_paired_predicate is out of range");
10778 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10779 emit_move_insn (target, tmp);
10784 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10786 rtx pat, scratch, tmp;
10787 tree form = CALL_EXPR_ARG (exp, 0);
10788 tree arg0 = CALL_EXPR_ARG (exp, 1);
10789 tree arg1 = CALL_EXPR_ARG (exp, 2);
10790 rtx op0 = expand_normal (arg0);
10791 rtx op1 = expand_normal (arg1);
10792 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10793 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10795 enum rtx_code code;
10797 if (TREE_CODE (form) != INTEGER_CST)
10799 error ("argument 1 of __builtin_spe_predicate must be a constant");
10803 form_int = TREE_INT_CST_LOW (form);
10805 gcc_assert (mode0 == mode1);
10807 if (arg0 == error_mark_node || arg1 == error_mark_node)
10811 || GET_MODE (target) != SImode
10812 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10813 target = gen_reg_rtx (SImode);
10815 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10816 op0 = copy_to_mode_reg (mode0, op0);
10817 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10818 op1 = copy_to_mode_reg (mode1, op1);
10820 scratch = gen_reg_rtx (CCmode);
10822 pat = GEN_FCN (icode) (scratch, op0, op1);
10827 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10828 _lower_. We use one compare, but look in different bits of the
10829 CR for each variant.
10831 There are 2 elements in each SPE simd type (upper/lower). The CR
10832 bits are set as follows:
10834 BIT0 | BIT 1 | BIT 2 | BIT 3
10835 U | L | (U | L) | (U & L)
10837 So, for an "all" relationship, BIT 3 would be set.
10838 For an "any" relationship, BIT 2 would be set. Etc.
10840 Following traditional nomenclature, these bits map to:
10842 BIT0 | BIT 1 | BIT 2 | BIT 3
10845 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10850 /* All variant. OV bit. */
10852 /* We need to get to the OV bit, which is the ORDERED bit. We
10853 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10854 that's ugly and will make validate_condition_mode die.
10855 So let's just use another pattern. */
10856 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10858 /* Any variant. EQ bit. */
10862 /* Upper variant. LT bit. */
10866 /* Lower variant. GT bit. */
10871 error ("argument 1 of __builtin_spe_predicate is out of range");
10875 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10876 emit_move_insn (target, tmp);
10881 /* The evsel builtins look like this:
10883 e = __builtin_spe_evsel_OP (a, b, c, d);
10885 and work like this:
10887 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10888 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10892 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10895 tree arg0 = CALL_EXPR_ARG (exp, 0);
10896 tree arg1 = CALL_EXPR_ARG (exp, 1);
10897 tree arg2 = CALL_EXPR_ARG (exp, 2);
10898 tree arg3 = CALL_EXPR_ARG (exp, 3);
10899 rtx op0 = expand_normal (arg0);
10900 rtx op1 = expand_normal (arg1);
10901 rtx op2 = expand_normal (arg2);
10902 rtx op3 = expand_normal (arg3);
10903 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10904 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10906 gcc_assert (mode0 == mode1);
10908 if (arg0 == error_mark_node || arg1 == error_mark_node
10909 || arg2 == error_mark_node || arg3 == error_mark_node)
10913 || GET_MODE (target) != mode0
10914 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10915 target = gen_reg_rtx (mode0);
10917 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10918 op0 = copy_to_mode_reg (mode0, op0);
10919 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10920 op1 = copy_to_mode_reg (mode0, op1);
10921 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10922 op2 = copy_to_mode_reg (mode0, op2);
10923 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10924 op3 = copy_to_mode_reg (mode0, op3);
10926 /* Generate the compare. */
10927 scratch = gen_reg_rtx (CCmode);
10928 pat = GEN_FCN (icode) (scratch, op0, op1);
10933 if (mode0 == V2SImode)
10934 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10936 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10941 /* Expand an expression EXP that calls a built-in function,
10942 with result going to TARGET if that's convenient
10943 (and in mode MODE if that's convenient).
10944 SUBTARGET may be used as the target for computing one of EXP's operands.
10945 IGNORE is nonzero if the value is to be ignored. */
10948 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10949 enum machine_mode mode ATTRIBUTE_UNUSED,
10950 int ignore ATTRIBUTE_UNUSED)
10952 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10953 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10954 const struct builtin_description *d;
10959 if (fcode == RS6000_BUILTIN_RECIP)
10960 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10962 if (fcode == RS6000_BUILTIN_RECIPF)
10963 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10965 if (fcode == RS6000_BUILTIN_RSQRTF)
10966 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10968 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10969 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10971 if (fcode == POWER7_BUILTIN_BPERMD)
10972 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10973 ? CODE_FOR_bpermd_di
10974 : CODE_FOR_bpermd_si), exp, target);
10976 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10977 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10979 int icode = (int) CODE_FOR_altivec_lvsr;
10980 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10981 enum machine_mode mode = insn_data[icode].operand[1].mode;
10985 gcc_assert (TARGET_ALTIVEC);
10987 arg = CALL_EXPR_ARG (exp, 0);
10988 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10989 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10990 addr = memory_address (mode, op);
10991 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10995 /* For the load case need to negate the address. */
10996 op = gen_reg_rtx (GET_MODE (addr));
10997 emit_insn (gen_rtx_SET (VOIDmode, op,
10998 gen_rtx_NEG (GET_MODE (addr), addr)));
11000 op = gen_rtx_MEM (mode, op);
11003 || GET_MODE (target) != tmode
11004 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11005 target = gen_reg_rtx (tmode);
11007 /*pat = gen_altivec_lvsr (target, op);*/
11008 pat = GEN_FCN (icode) (target, op);
11016 /* FIXME: There's got to be a nicer way to handle this case than
11017 constructing a new CALL_EXPR. */
11018 if (fcode == ALTIVEC_BUILTIN_VCFUX
11019 || fcode == ALTIVEC_BUILTIN_VCFSX
11020 || fcode == ALTIVEC_BUILTIN_VCTUXS
11021 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11023 if (call_expr_nargs (exp) == 1)
11024 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11025 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11028 if (TARGET_ALTIVEC)
11030 ret = altivec_expand_builtin (exp, target, &success);
11037 ret = spe_expand_builtin (exp, target, &success);
11042 if (TARGET_PAIRED_FLOAT)
11044 ret = paired_expand_builtin (exp, target, &success);
11050 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11052 /* Handle simple unary operations. */
11053 d = (struct builtin_description *) bdesc_1arg;
11054 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11055 if (d->code == fcode)
11056 return rs6000_expand_unop_builtin (d->icode, exp, target);
11058 /* Handle simple binary operations. */
11059 d = (struct builtin_description *) bdesc_2arg;
11060 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11061 if (d->code == fcode)
11062 return rs6000_expand_binop_builtin (d->icode, exp, target);
11064 /* Handle simple ternary operations. */
11066 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11067 if (d->code == fcode)
11068 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11070 gcc_unreachable ();
11074 rs6000_init_builtins (void)
11078 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11079 V2SF_type_node = build_vector_type (float_type_node, 2);
11080 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11081 V2DF_type_node = build_vector_type (double_type_node, 2);
11082 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11083 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11084 V4SF_type_node = build_vector_type (float_type_node, 4);
11085 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11086 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11088 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11089 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11090 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11091 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11093 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11094 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11095 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11096 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11098 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11099 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11100 'vector unsigned short'. */
11102 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11103 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11104 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11105 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11106 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11108 long_integer_type_internal_node = long_integer_type_node;
11109 long_unsigned_type_internal_node = long_unsigned_type_node;
11110 intQI_type_internal_node = intQI_type_node;
11111 uintQI_type_internal_node = unsigned_intQI_type_node;
11112 intHI_type_internal_node = intHI_type_node;
11113 uintHI_type_internal_node = unsigned_intHI_type_node;
11114 intSI_type_internal_node = intSI_type_node;
11115 uintSI_type_internal_node = unsigned_intSI_type_node;
11116 intDI_type_internal_node = intDI_type_node;
11117 uintDI_type_internal_node = unsigned_intDI_type_node;
11118 float_type_internal_node = float_type_node;
11119 double_type_internal_node = float_type_node;
11120 void_type_internal_node = void_type_node;
11122 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11124 builtin_mode_to_type[QImode][0] = integer_type_node;
11125 builtin_mode_to_type[HImode][0] = integer_type_node;
11126 builtin_mode_to_type[SImode][0] = intSI_type_node;
11127 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11128 builtin_mode_to_type[DImode][0] = intDI_type_node;
11129 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11130 builtin_mode_to_type[SFmode][0] = float_type_node;
11131 builtin_mode_to_type[DFmode][0] = double_type_node;
11132 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11133 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11134 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11135 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11136 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11137 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11138 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11139 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11140 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11141 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11142 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11143 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11144 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11146 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11147 get_identifier ("__bool char"),
11148 bool_char_type_node);
11149 TYPE_NAME (bool_char_type_node) = tdecl;
11150 (*lang_hooks.decls.pushdecl) (tdecl);
11151 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11152 get_identifier ("__bool short"),
11153 bool_short_type_node);
11154 TYPE_NAME (bool_short_type_node) = tdecl;
11155 (*lang_hooks.decls.pushdecl) (tdecl);
11156 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11157 get_identifier ("__bool int"),
11158 bool_int_type_node);
11159 TYPE_NAME (bool_int_type_node) = tdecl;
11160 (*lang_hooks.decls.pushdecl) (tdecl);
11161 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11163 TYPE_NAME (pixel_type_node) = tdecl;
11164 (*lang_hooks.decls.pushdecl) (tdecl);
11166 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11167 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11168 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11169 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11170 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11172 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11173 get_identifier ("__vector unsigned char"),
11174 unsigned_V16QI_type_node);
11175 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11176 (*lang_hooks.decls.pushdecl) (tdecl);
11177 tdecl = build_decl (BUILTINS_LOCATION,
11178 TYPE_DECL, get_identifier ("__vector signed char"),
11180 TYPE_NAME (V16QI_type_node) = tdecl;
11181 (*lang_hooks.decls.pushdecl) (tdecl);
11182 tdecl = build_decl (BUILTINS_LOCATION,
11183 TYPE_DECL, get_identifier ("__vector __bool char"),
11184 bool_V16QI_type_node);
11185 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11186 (*lang_hooks.decls.pushdecl) (tdecl);
11188 tdecl = build_decl (BUILTINS_LOCATION,
11189 TYPE_DECL, get_identifier ("__vector unsigned short"),
11190 unsigned_V8HI_type_node);
11191 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11192 (*lang_hooks.decls.pushdecl) (tdecl);
11193 tdecl = build_decl (BUILTINS_LOCATION,
11194 TYPE_DECL, get_identifier ("__vector signed short"),
11196 TYPE_NAME (V8HI_type_node) = tdecl;
11197 (*lang_hooks.decls.pushdecl) (tdecl);
11198 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11199 get_identifier ("__vector __bool short"),
11200 bool_V8HI_type_node);
11201 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11202 (*lang_hooks.decls.pushdecl) (tdecl);
11204 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11205 get_identifier ("__vector unsigned int"),
11206 unsigned_V4SI_type_node);
11207 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11208 (*lang_hooks.decls.pushdecl) (tdecl);
11209 tdecl = build_decl (BUILTINS_LOCATION,
11210 TYPE_DECL, get_identifier ("__vector signed int"),
11212 TYPE_NAME (V4SI_type_node) = tdecl;
11213 (*lang_hooks.decls.pushdecl) (tdecl);
11214 tdecl = build_decl (BUILTINS_LOCATION,
11215 TYPE_DECL, get_identifier ("__vector __bool int"),
11216 bool_V4SI_type_node);
11217 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11218 (*lang_hooks.decls.pushdecl) (tdecl);
11220 tdecl = build_decl (BUILTINS_LOCATION,
11221 TYPE_DECL, get_identifier ("__vector float"),
11223 TYPE_NAME (V4SF_type_node) = tdecl;
11224 (*lang_hooks.decls.pushdecl) (tdecl);
11225 tdecl = build_decl (BUILTINS_LOCATION,
11226 TYPE_DECL, get_identifier ("__vector __pixel"),
11227 pixel_V8HI_type_node);
11228 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11229 (*lang_hooks.decls.pushdecl) (tdecl);
11233 tdecl = build_decl (BUILTINS_LOCATION,
11234 TYPE_DECL, get_identifier ("__vector double"),
11236 TYPE_NAME (V2DF_type_node) = tdecl;
11237 (*lang_hooks.decls.pushdecl) (tdecl);
11239 tdecl = build_decl (BUILTINS_LOCATION,
11240 TYPE_DECL, get_identifier ("__vector long"),
11242 TYPE_NAME (V2DI_type_node) = tdecl;
11243 (*lang_hooks.decls.pushdecl) (tdecl);
11245 tdecl = build_decl (BUILTINS_LOCATION,
11246 TYPE_DECL, get_identifier ("__vector unsigned long"),
11247 unsigned_V2DI_type_node);
11248 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11249 (*lang_hooks.decls.pushdecl) (tdecl);
11251 tdecl = build_decl (BUILTINS_LOCATION,
11252 TYPE_DECL, get_identifier ("__vector __bool long"),
11253 bool_V2DI_type_node);
11254 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11255 (*lang_hooks.decls.pushdecl) (tdecl);
11258 if (TARGET_PAIRED_FLOAT)
11259 paired_init_builtins ();
11261 spe_init_builtins ();
11262 if (TARGET_ALTIVEC)
11263 altivec_init_builtins ();
11264 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11265 rs6000_common_init_builtins ();
11266 if (TARGET_PPC_GFXOPT)
11268 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11269 RS6000_BUILTIN_RECIPF,
11270 "__builtin_recipdivf");
11271 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11272 RS6000_BUILTIN_RECIPF);
11274 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11275 RS6000_BUILTIN_RSQRTF,
11276 "__builtin_rsqrtf");
11277 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11278 RS6000_BUILTIN_RSQRTF);
11280 if (TARGET_POPCNTB)
11282 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11283 RS6000_BUILTIN_RECIP,
11284 "__builtin_recipdiv");
11285 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11286 RS6000_BUILTIN_RECIP);
11289 if (TARGET_POPCNTD)
11291 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11292 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11293 POWER7_BUILTIN_BPERMD,
11294 "__builtin_bpermd");
11295 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11296 POWER7_BUILTIN_BPERMD);
11298 if (TARGET_POWERPC)
11300 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11301 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11302 unsigned_intHI_type_node,
11304 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11305 RS6000_BUILTIN_BSWAP_HI);
11309 /* AIX libm provides clog as __clog. */
11310 if (built_in_decls [BUILT_IN_CLOG])
11311 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11314 #ifdef SUBTARGET_INIT_BUILTINS
11315 SUBTARGET_INIT_BUILTINS;
11319 /* Returns the rs6000 builtin decl for CODE. */
11322 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11324 if (code >= RS6000_BUILTIN_COUNT)
11325 return error_mark_node;
11327 return rs6000_builtin_decls[code];
11330 /* Search through a set of builtins and enable the mask bits.
11331 DESC is an array of builtins.
11332 SIZE is the total number of builtins.
11333 START is the builtin enum at which to start.
11334 END is the builtin enum at which to end. */
11336 enable_mask_for_builtins (struct builtin_description *desc, int size,
11337 enum rs6000_builtins start,
11338 enum rs6000_builtins end)
11342 for (i = 0; i < size; ++i)
11343 if (desc[i].code == start)
11349 for (; i < size; ++i)
11351 /* Flip all the bits on. */
11352 desc[i].mask = target_flags;
11353 if (desc[i].code == end)
11359 spe_init_builtins (void)
11361 tree endlink = void_list_node;
11362 tree puint_type_node = build_pointer_type (unsigned_type_node);
11363 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11364 struct builtin_description *d;
11367 tree v2si_ftype_4_v2si
11368 = build_function_type
11369 (opaque_V2SI_type_node,
11370 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11371 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11372 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11373 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11376 tree v2sf_ftype_4_v2sf
11377 = build_function_type
11378 (opaque_V2SF_type_node,
11379 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11380 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11381 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11382 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11385 tree int_ftype_int_v2si_v2si
11386 = build_function_type
11387 (integer_type_node,
11388 tree_cons (NULL_TREE, integer_type_node,
11389 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11390 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11393 tree int_ftype_int_v2sf_v2sf
11394 = build_function_type
11395 (integer_type_node,
11396 tree_cons (NULL_TREE, integer_type_node,
11397 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11398 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11401 tree void_ftype_v2si_puint_int
11402 = build_function_type (void_type_node,
11403 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11404 tree_cons (NULL_TREE, puint_type_node,
11405 tree_cons (NULL_TREE,
11409 tree void_ftype_v2si_puint_char
11410 = build_function_type (void_type_node,
11411 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11412 tree_cons (NULL_TREE, puint_type_node,
11413 tree_cons (NULL_TREE,
11417 tree void_ftype_v2si_pv2si_int
11418 = build_function_type (void_type_node,
11419 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11420 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11421 tree_cons (NULL_TREE,
11425 tree void_ftype_v2si_pv2si_char
11426 = build_function_type (void_type_node,
11427 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11428 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11429 tree_cons (NULL_TREE,
11433 tree void_ftype_int
11434 = build_function_type (void_type_node,
11435 tree_cons (NULL_TREE, integer_type_node, endlink));
11437 tree int_ftype_void
11438 = build_function_type (integer_type_node, endlink);
11440 tree v2si_ftype_pv2si_int
11441 = build_function_type (opaque_V2SI_type_node,
11442 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11443 tree_cons (NULL_TREE, integer_type_node,
11446 tree v2si_ftype_puint_int
11447 = build_function_type (opaque_V2SI_type_node,
11448 tree_cons (NULL_TREE, puint_type_node,
11449 tree_cons (NULL_TREE, integer_type_node,
11452 tree v2si_ftype_pushort_int
11453 = build_function_type (opaque_V2SI_type_node,
11454 tree_cons (NULL_TREE, pushort_type_node,
11455 tree_cons (NULL_TREE, integer_type_node,
11458 tree v2si_ftype_signed_char
11459 = build_function_type (opaque_V2SI_type_node,
11460 tree_cons (NULL_TREE, signed_char_type_node,
11463 /* The initialization of the simple binary and unary builtins is
11464 done in rs6000_common_init_builtins, but we have to enable the
11465 mask bits here manually because we have run out of `target_flags'
11466 bits. We really need to redesign this mask business. */
11468 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11469 ARRAY_SIZE (bdesc_2arg),
11470 SPE_BUILTIN_EVADDW,
11471 SPE_BUILTIN_EVXOR);
11472 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11473 ARRAY_SIZE (bdesc_1arg),
11475 SPE_BUILTIN_EVSUBFUSIAAW);
11476 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11477 ARRAY_SIZE (bdesc_spe_predicates),
11478 SPE_BUILTIN_EVCMPEQ,
11479 SPE_BUILTIN_EVFSTSTLT);
11480 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11481 ARRAY_SIZE (bdesc_spe_evsel),
11482 SPE_BUILTIN_EVSEL_CMPGTS,
11483 SPE_BUILTIN_EVSEL_FSTSTEQ);
11485 (*lang_hooks.decls.pushdecl)
11486 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11487 get_identifier ("__ev64_opaque__"),
11488 opaque_V2SI_type_node));
11490 /* Initialize irregular SPE builtins. */
11492 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11493 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11494 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11495 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11496 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11497 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11498 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11499 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11500 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11501 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11502 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11503 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11504 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11505 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11506 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11507 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11508 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11509 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11512 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11513 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11514 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11515 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11516 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11517 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11518 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11519 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11520 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11521 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11522 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11523 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11524 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11525 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11526 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11527 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11528 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11529 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11530 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11531 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11532 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11533 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11536 d = (struct builtin_description *) bdesc_spe_predicates;
11537 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11541 switch (insn_data[d->icode].operand[1].mode)
11544 type = int_ftype_int_v2si_v2si;
11547 type = int_ftype_int_v2sf_v2sf;
11550 gcc_unreachable ();
11553 def_builtin (d->mask, d->name, type, d->code);
11556 /* Evsel predicates. */
11557 d = (struct builtin_description *) bdesc_spe_evsel;
11558 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11562 switch (insn_data[d->icode].operand[1].mode)
11565 type = v2si_ftype_4_v2si;
11568 type = v2sf_ftype_4_v2sf;
11571 gcc_unreachable ();
11574 def_builtin (d->mask, d->name, type, d->code);
11579 paired_init_builtins (void)
11581 const struct builtin_description *d;
11583 tree endlink = void_list_node;
11585 tree int_ftype_int_v2sf_v2sf
11586 = build_function_type
11587 (integer_type_node,
11588 tree_cons (NULL_TREE, integer_type_node,
11589 tree_cons (NULL_TREE, V2SF_type_node,
11590 tree_cons (NULL_TREE, V2SF_type_node,
11592 tree pcfloat_type_node =
11593 build_pointer_type (build_qualified_type
11594 (float_type_node, TYPE_QUAL_CONST));
11596 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11597 long_integer_type_node,
11600 tree void_ftype_v2sf_long_pcfloat =
11601 build_function_type_list (void_type_node,
11603 long_integer_type_node,
11608 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11609 PAIRED_BUILTIN_LX);
11612 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11613 PAIRED_BUILTIN_STX);
11616 d = bdesc_paired_preds;
11617 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11621 switch (insn_data[d->icode].operand[1].mode)
11624 type = int_ftype_int_v2sf_v2sf;
11627 gcc_unreachable ();
11630 def_builtin (d->mask, d->name, type, d->code);
11635 altivec_init_builtins (void)
11637 const struct builtin_description *d;
11638 const struct builtin_description_predicates *dp;
11642 tree pfloat_type_node = build_pointer_type (float_type_node);
11643 tree pint_type_node = build_pointer_type (integer_type_node);
11644 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11645 tree pchar_type_node = build_pointer_type (char_type_node);
11647 tree pvoid_type_node = build_pointer_type (void_type_node);
11649 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11650 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11651 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11652 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11654 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11656 tree int_ftype_opaque
11657 = build_function_type_list (integer_type_node,
11658 opaque_V4SI_type_node, NULL_TREE);
11659 tree opaque_ftype_opaque
11660 = build_function_type (integer_type_node,
11662 tree opaque_ftype_opaque_int
11663 = build_function_type_list (opaque_V4SI_type_node,
11664 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11665 tree opaque_ftype_opaque_opaque_int
11666 = build_function_type_list (opaque_V4SI_type_node,
11667 opaque_V4SI_type_node, opaque_V4SI_type_node,
11668 integer_type_node, NULL_TREE);
11669 tree int_ftype_int_opaque_opaque
11670 = build_function_type_list (integer_type_node,
11671 integer_type_node, opaque_V4SI_type_node,
11672 opaque_V4SI_type_node, NULL_TREE);
11673 tree int_ftype_int_v4si_v4si
11674 = build_function_type_list (integer_type_node,
11675 integer_type_node, V4SI_type_node,
11676 V4SI_type_node, NULL_TREE);
11677 tree v4sf_ftype_pcfloat
11678 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11679 tree void_ftype_pfloat_v4sf
11680 = build_function_type_list (void_type_node,
11681 pfloat_type_node, V4SF_type_node, NULL_TREE);
11682 tree v4si_ftype_pcint
11683 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11684 tree void_ftype_pint_v4si
11685 = build_function_type_list (void_type_node,
11686 pint_type_node, V4SI_type_node, NULL_TREE);
11687 tree v8hi_ftype_pcshort
11688 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11689 tree void_ftype_pshort_v8hi
11690 = build_function_type_list (void_type_node,
11691 pshort_type_node, V8HI_type_node, NULL_TREE);
11692 tree v16qi_ftype_pcchar
11693 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11694 tree void_ftype_pchar_v16qi
11695 = build_function_type_list (void_type_node,
11696 pchar_type_node, V16QI_type_node, NULL_TREE);
11697 tree void_ftype_v4si
11698 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11699 tree v8hi_ftype_void
11700 = build_function_type (V8HI_type_node, void_list_node);
11701 tree void_ftype_void
11702 = build_function_type (void_type_node, void_list_node);
11703 tree void_ftype_int
11704 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11706 tree opaque_ftype_long_pcvoid
11707 = build_function_type_list (opaque_V4SI_type_node,
11708 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11709 tree v16qi_ftype_long_pcvoid
11710 = build_function_type_list (V16QI_type_node,
11711 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11712 tree v8hi_ftype_long_pcvoid
11713 = build_function_type_list (V8HI_type_node,
11714 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11715 tree v4si_ftype_long_pcvoid
11716 = build_function_type_list (V4SI_type_node,
11717 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11719 tree void_ftype_opaque_long_pvoid
11720 = build_function_type_list (void_type_node,
11721 opaque_V4SI_type_node, long_integer_type_node,
11722 pvoid_type_node, NULL_TREE);
11723 tree void_ftype_v4si_long_pvoid
11724 = build_function_type_list (void_type_node,
11725 V4SI_type_node, long_integer_type_node,
11726 pvoid_type_node, NULL_TREE);
11727 tree void_ftype_v16qi_long_pvoid
11728 = build_function_type_list (void_type_node,
11729 V16QI_type_node, long_integer_type_node,
11730 pvoid_type_node, NULL_TREE);
11731 tree void_ftype_v8hi_long_pvoid
11732 = build_function_type_list (void_type_node,
11733 V8HI_type_node, long_integer_type_node,
11734 pvoid_type_node, NULL_TREE);
11735 tree int_ftype_int_v8hi_v8hi
11736 = build_function_type_list (integer_type_node,
11737 integer_type_node, V8HI_type_node,
11738 V8HI_type_node, NULL_TREE);
11739 tree int_ftype_int_v16qi_v16qi
11740 = build_function_type_list (integer_type_node,
11741 integer_type_node, V16QI_type_node,
11742 V16QI_type_node, NULL_TREE);
11743 tree int_ftype_int_v4sf_v4sf
11744 = build_function_type_list (integer_type_node,
11745 integer_type_node, V4SF_type_node,
11746 V4SF_type_node, NULL_TREE);
11747 tree int_ftype_int_v2df_v2df
11748 = build_function_type_list (integer_type_node,
11749 integer_type_node, V2DF_type_node,
11750 V2DF_type_node, NULL_TREE);
11751 tree v4si_ftype_v4si
11752 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11753 tree v8hi_ftype_v8hi
11754 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11755 tree v16qi_ftype_v16qi
11756 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11757 tree v4sf_ftype_v4sf
11758 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11759 tree v2df_ftype_v2df
11760 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11761 tree void_ftype_pcvoid_int_int
11762 = build_function_type_list (void_type_node,
11763 pcvoid_type_node, integer_type_node,
11764 integer_type_node, NULL_TREE);
11766 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11767 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11768 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11769 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11770 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11771 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11772 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11773 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11774 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11775 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11776 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11777 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11778 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11779 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11781 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11783 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11785 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11787 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11798 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11799 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11800 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11801 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11802 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11804 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11805 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11807 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11808 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11810 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11811 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11813 if (rs6000_cpu == PROCESSOR_CELL)
11815 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11816 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11817 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11818 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11820 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11825 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11826 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11827 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11828 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11830 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11831 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11832 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11833 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11835 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11836 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11839 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11840 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11841 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11842 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11843 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11844 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11845 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11850 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11852 /* Add the DST variants. */
11854 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11855 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11857 /* Initialize the predicates. */
11858 dp = bdesc_altivec_preds;
11859 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11861 enum machine_mode mode1;
11863 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11864 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11865 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11866 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11871 mode1 = insn_data[dp->icode].operand[1].mode;
11876 type = int_ftype_int_opaque_opaque;
11879 type = int_ftype_int_v4si_v4si;
11882 type = int_ftype_int_v8hi_v8hi;
11885 type = int_ftype_int_v16qi_v16qi;
11888 type = int_ftype_int_v4sf_v4sf;
11891 type = int_ftype_int_v2df_v2df;
11894 gcc_unreachable ();
11897 def_builtin (dp->mask, dp->name, type, dp->code);
11900 /* Initialize the abs* operators. */
11902 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11904 enum machine_mode mode0;
11907 mode0 = insn_data[d->icode].operand[0].mode;
11912 type = v4si_ftype_v4si;
11915 type = v8hi_ftype_v8hi;
11918 type = v16qi_ftype_v16qi;
11921 type = v4sf_ftype_v4sf;
11924 type = v2df_ftype_v2df;
11927 gcc_unreachable ();
11930 def_builtin (d->mask, d->name, type, d->code);
11933 if (TARGET_ALTIVEC)
11937 /* Initialize target builtin that implements
11938 targetm.vectorize.builtin_mask_for_load. */
11940 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11941 v16qi_ftype_long_pcvoid,
11942 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11943 BUILT_IN_MD, NULL, NULL_TREE);
11944 TREE_READONLY (decl) = 1;
11945 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11946 altivec_builtin_mask_for_load = decl;
11949 /* Access to the vec_init patterns. */
11950 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11951 integer_type_node, integer_type_node,
11952 integer_type_node, NULL_TREE);
11953 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11954 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11956 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11957 short_integer_type_node,
11958 short_integer_type_node,
11959 short_integer_type_node,
11960 short_integer_type_node,
11961 short_integer_type_node,
11962 short_integer_type_node,
11963 short_integer_type_node, NULL_TREE);
11964 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11965 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11967 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11968 char_type_node, char_type_node,
11969 char_type_node, char_type_node,
11970 char_type_node, char_type_node,
11971 char_type_node, char_type_node,
11972 char_type_node, char_type_node,
11973 char_type_node, char_type_node,
11974 char_type_node, char_type_node,
11975 char_type_node, NULL_TREE);
11976 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11977 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11979 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11980 float_type_node, float_type_node,
11981 float_type_node, NULL_TREE);
11982 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11983 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11987 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11988 double_type_node, NULL_TREE);
11989 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11990 VSX_BUILTIN_VEC_INIT_V2DF);
11992 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11993 intDI_type_node, NULL_TREE);
11994 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11995 VSX_BUILTIN_VEC_INIT_V2DI);
11998 /* Access to the vec_set patterns. */
11999 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12001 integer_type_node, NULL_TREE);
12002 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12003 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12005 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12007 integer_type_node, NULL_TREE);
12008 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12009 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12011 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12013 integer_type_node, NULL_TREE);
12014 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12015 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12017 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12019 integer_type_node, NULL_TREE);
12020 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12021 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12025 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12027 integer_type_node, NULL_TREE);
12028 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12029 VSX_BUILTIN_VEC_SET_V2DF);
12031 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12033 integer_type_node, NULL_TREE);
12034 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12035 VSX_BUILTIN_VEC_SET_V2DI);
12038 /* Access to the vec_extract patterns. */
12039 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12040 integer_type_node, NULL_TREE);
12041 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12042 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12044 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12045 integer_type_node, NULL_TREE);
12046 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12047 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12049 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12050 integer_type_node, NULL_TREE);
12051 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12052 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12054 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12055 integer_type_node, NULL_TREE);
12056 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12057 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12061 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12062 integer_type_node, NULL_TREE);
12063 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12064 VSX_BUILTIN_VEC_EXT_V2DF);
12066 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12067 integer_type_node, NULL_TREE);
12068 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12069 VSX_BUILTIN_VEC_EXT_V2DI);
12073 /* Hash function for builtin functions with up to 3 arguments and a return
12076 builtin_hash_function (const void *hash_entry)
12080 const struct builtin_hash_struct *bh =
12081 (const struct builtin_hash_struct *) hash_entry;
12083 for (i = 0; i < 4; i++)
12085 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12086 ret = (ret * 2) + bh->uns_p[i];
12092 /* Compare builtin hash entries H1 and H2 for equivalence. */
12094 builtin_hash_eq (const void *h1, const void *h2)
12096 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12097 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12099 return ((p1->mode[0] == p2->mode[0])
12100 && (p1->mode[1] == p2->mode[1])
12101 && (p1->mode[2] == p2->mode[2])
12102 && (p1->mode[3] == p2->mode[3])
12103 && (p1->uns_p[0] == p2->uns_p[0])
12104 && (p1->uns_p[1] == p2->uns_p[1])
12105 && (p1->uns_p[2] == p2->uns_p[2])
12106 && (p1->uns_p[3] == p2->uns_p[3]));
12109 /* Map types for builtin functions with an explicit return type and up to 3
12110 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12111 of the argument. */
12113 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12114 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12115 enum rs6000_builtins builtin, const char *name)
12117 struct builtin_hash_struct h;
12118 struct builtin_hash_struct *h2;
12122 tree ret_type = NULL_TREE;
12123 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12126 /* Create builtin_hash_table. */
12127 if (builtin_hash_table == NULL)
12128 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12129 builtin_hash_eq, NULL);
12131 h.type = NULL_TREE;
12132 h.mode[0] = mode_ret;
12133 h.mode[1] = mode_arg0;
12134 h.mode[2] = mode_arg1;
12135 h.mode[3] = mode_arg2;
12141 /* If the builtin is a type that produces unsigned results or takes unsigned
12142 arguments, and it is returned as a decl for the vectorizer (such as
12143 widening multiplies, permute), make sure the arguments and return value
12144 are type correct. */
12147 /* unsigned 2 argument functions. */
12148 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12149 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12150 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12151 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12157 /* unsigned 3 argument functions. */
12158 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12159 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12160 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12161 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12162 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12163 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12164 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12165 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12166 case VSX_BUILTIN_VPERM_16QI_UNS:
12167 case VSX_BUILTIN_VPERM_8HI_UNS:
12168 case VSX_BUILTIN_VPERM_4SI_UNS:
12169 case VSX_BUILTIN_VPERM_2DI_UNS:
12170 case VSX_BUILTIN_XXSEL_16QI_UNS:
12171 case VSX_BUILTIN_XXSEL_8HI_UNS:
12172 case VSX_BUILTIN_XXSEL_4SI_UNS:
12173 case VSX_BUILTIN_XXSEL_2DI_UNS:
12180 /* signed permute functions with unsigned char mask. */
12181 case ALTIVEC_BUILTIN_VPERM_16QI:
12182 case ALTIVEC_BUILTIN_VPERM_8HI:
12183 case ALTIVEC_BUILTIN_VPERM_4SI:
12184 case ALTIVEC_BUILTIN_VPERM_4SF:
12185 case ALTIVEC_BUILTIN_VPERM_2DI:
12186 case ALTIVEC_BUILTIN_VPERM_2DF:
12187 case VSX_BUILTIN_VPERM_16QI:
12188 case VSX_BUILTIN_VPERM_8HI:
12189 case VSX_BUILTIN_VPERM_4SI:
12190 case VSX_BUILTIN_VPERM_4SF:
12191 case VSX_BUILTIN_VPERM_2DI:
12192 case VSX_BUILTIN_VPERM_2DF:
12196 /* unsigned args, signed return. */
12197 case VSX_BUILTIN_XVCVUXDDP_UNS:
12198 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12202 /* signed args, unsigned return. */
12203 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12204 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12212 /* Figure out how many args are present. */
12213 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12217 fatal_error ("internal error: builtin function %s had no type", name);
12219 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12220 if (!ret_type && h.uns_p[0])
12221 ret_type = builtin_mode_to_type[h.mode[0]][0];
12224 fatal_error ("internal error: builtin function %s had an unexpected "
12225 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12227 for (i = 0; i < num_args; i++)
12229 int m = (int) h.mode[i+1];
12230 int uns_p = h.uns_p[i+1];
12232 arg_type[i] = builtin_mode_to_type[m][uns_p];
12233 if (!arg_type[i] && uns_p)
12234 arg_type[i] = builtin_mode_to_type[m][0];
12237 fatal_error ("internal error: builtin function %s, argument %d "
12238 "had unexpected argument type %s", name, i,
12239 GET_MODE_NAME (m));
12242 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12243 if (*found == NULL)
12245 h2 = GGC_NEW (struct builtin_hash_struct);
12247 *found = (void *)h2;
12248 args = void_list_node;
12250 for (i = num_args - 1; i >= 0; i--)
12251 args = tree_cons (NULL_TREE, arg_type[i], args);
12253 h2->type = build_function_type (ret_type, args);
12256 return ((struct builtin_hash_struct *)(*found))->type;
12260 rs6000_common_init_builtins (void)
12262 const struct builtin_description *d;
12265 tree opaque_ftype_opaque = NULL_TREE;
12266 tree opaque_ftype_opaque_opaque = NULL_TREE;
12267 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12268 tree v2si_ftype_qi = NULL_TREE;
12269 tree v2si_ftype_v2si_qi = NULL_TREE;
12270 tree v2si_ftype_int_qi = NULL_TREE;
12272 if (!TARGET_PAIRED_FLOAT)
12274 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12275 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12278 /* Add the ternary operators. */
12280 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12283 int mask = d->mask;
12285 if ((mask != 0 && (mask & target_flags) == 0)
12286 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12289 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12290 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12291 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12292 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12294 if (! (type = opaque_ftype_opaque_opaque_opaque))
12295 type = opaque_ftype_opaque_opaque_opaque
12296 = build_function_type_list (opaque_V4SI_type_node,
12297 opaque_V4SI_type_node,
12298 opaque_V4SI_type_node,
12299 opaque_V4SI_type_node,
12304 enum insn_code icode = d->icode;
12305 if (d->name == 0 || icode == CODE_FOR_nothing)
12308 type = builtin_function_type (insn_data[icode].operand[0].mode,
12309 insn_data[icode].operand[1].mode,
12310 insn_data[icode].operand[2].mode,
12311 insn_data[icode].operand[3].mode,
12315 def_builtin (d->mask, d->name, type, d->code);
12318 /* Add the binary operators. */
12320 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12322 enum machine_mode mode0, mode1, mode2;
12324 int mask = d->mask;
12326 if ((mask != 0 && (mask & target_flags) == 0)
12327 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12330 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12331 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12332 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12333 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12335 if (! (type = opaque_ftype_opaque_opaque))
12336 type = opaque_ftype_opaque_opaque
12337 = build_function_type_list (opaque_V4SI_type_node,
12338 opaque_V4SI_type_node,
12339 opaque_V4SI_type_node,
12344 enum insn_code icode = d->icode;
12345 if (d->name == 0 || icode == CODE_FOR_nothing)
12348 mode0 = insn_data[icode].operand[0].mode;
12349 mode1 = insn_data[icode].operand[1].mode;
12350 mode2 = insn_data[icode].operand[2].mode;
12352 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12354 if (! (type = v2si_ftype_v2si_qi))
12355 type = v2si_ftype_v2si_qi
12356 = build_function_type_list (opaque_V2SI_type_node,
12357 opaque_V2SI_type_node,
12362 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12363 && mode2 == QImode)
12365 if (! (type = v2si_ftype_int_qi))
12366 type = v2si_ftype_int_qi
12367 = build_function_type_list (opaque_V2SI_type_node,
12374 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12378 def_builtin (d->mask, d->name, type, d->code);
12381 /* Add the simple unary operators. */
12382 d = (struct builtin_description *) bdesc_1arg;
12383 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12385 enum machine_mode mode0, mode1;
12387 int mask = d->mask;
12389 if ((mask != 0 && (mask & target_flags) == 0)
12390 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12393 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12394 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12395 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12396 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12398 if (! (type = opaque_ftype_opaque))
12399 type = opaque_ftype_opaque
12400 = build_function_type_list (opaque_V4SI_type_node,
12401 opaque_V4SI_type_node,
12406 enum insn_code icode = d->icode;
12407 if (d->name == 0 || icode == CODE_FOR_nothing)
12410 mode0 = insn_data[icode].operand[0].mode;
12411 mode1 = insn_data[icode].operand[1].mode;
12413 if (mode0 == V2SImode && mode1 == QImode)
12415 if (! (type = v2si_ftype_qi))
12416 type = v2si_ftype_qi
12417 = build_function_type_list (opaque_V2SI_type_node,
12423 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12427 def_builtin (d->mask, d->name, type, d->code);
12432 rs6000_init_libfuncs (void)
12434 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12435 && !TARGET_POWER2 && !TARGET_POWERPC)
12437 /* AIX library routines for float->int conversion. */
12438 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12439 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12440 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12441 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12444 if (!TARGET_IEEEQUAD)
12445 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12446 if (!TARGET_XL_COMPAT)
12448 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12449 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12450 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12451 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12453 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12455 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12456 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12457 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12458 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12459 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12460 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12461 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12463 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12464 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12465 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12466 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12467 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12468 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12469 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12470 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12473 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12474 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12478 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12479 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12480 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12481 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12485 /* 32-bit SVR4 quad floating point routines. */
12487 set_optab_libfunc (add_optab, TFmode, "_q_add");
12488 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12489 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12490 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12491 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12492 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12493 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12495 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12496 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12497 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12498 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12499 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12500 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12502 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12503 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12504 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12505 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12506 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12507 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12508 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12509 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12514 /* Expand a block clear operation, and return 1 if successful. Return 0
12515 if we should let the compiler generate normal code.
12517 operands[0] is the destination
12518 operands[1] is the length
12519 operands[3] is the alignment */
12522 expand_block_clear (rtx operands[])
12524 rtx orig_dest = operands[0];
12525 rtx bytes_rtx = operands[1];
12526 rtx align_rtx = operands[3];
12527 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12528 HOST_WIDE_INT align;
12529 HOST_WIDE_INT bytes;
12534 /* If this is not a fixed size move, just call memcpy */
12538 /* This must be a fixed size alignment */
12539 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12540 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12542 /* Anything to clear? */
12543 bytes = INTVAL (bytes_rtx);
12547 /* Use the builtin memset after a point, to avoid huge code bloat.
12548 When optimize_size, avoid any significant code bloat; calling
12549 memset is about 4 instructions, so allow for one instruction to
12550 load zero and three to do clearing. */
12551 if (TARGET_ALTIVEC && align >= 128)
12553 else if (TARGET_POWERPC64 && align >= 32)
12555 else if (TARGET_SPE && align >= 64)
12560 if (optimize_size && bytes > 3 * clear_step)
12562 if (! optimize_size && bytes > 8 * clear_step)
12565 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12567 enum machine_mode mode = BLKmode;
12570 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12575 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12580 else if (bytes >= 8 && TARGET_POWERPC64
12581 /* 64-bit loads and stores require word-aligned
12583 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12588 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12589 { /* move 4 bytes */
12593 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12594 { /* move 2 bytes */
12598 else /* move 1 byte at a time */
12604 dest = adjust_address (orig_dest, mode, offset);
12606 emit_move_insn (dest, CONST0_RTX (mode));
12613 /* Expand a block move operation, and return 1 if successful. Return 0
12614 if we should let the compiler generate normal code.
12616 operands[0] is the destination
12617 operands[1] is the source
12618 operands[2] is the length
12619 operands[3] is the alignment */
12621 #define MAX_MOVE_REG 4
12624 expand_block_move (rtx operands[])
12626 rtx orig_dest = operands[0];
12627 rtx orig_src = operands[1];
12628 rtx bytes_rtx = operands[2];
12629 rtx align_rtx = operands[3];
12630 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12635 rtx stores[MAX_MOVE_REG];
12638 /* If this is not a fixed size move, just call memcpy */
12642 /* This must be a fixed size alignment */
12643 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12644 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12646 /* Anything to move? */
12647 bytes = INTVAL (bytes_rtx);
12651 /* store_one_arg depends on expand_block_move to handle at least the size of
12652 reg_parm_stack_space. */
12653 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12656 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12659 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12660 rtx (*mov) (rtx, rtx);
12662 enum machine_mode mode = BLKmode;
12665 /* Altivec first, since it will be faster than a string move
12666 when it applies, and usually not significantly larger. */
12667 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12671 gen_func.mov = gen_movv4si;
12673 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12677 gen_func.mov = gen_movv2si;
12679 else if (TARGET_STRING
12680 && bytes > 24 /* move up to 32 bytes at a time */
12686 && ! fixed_regs[10]
12687 && ! fixed_regs[11]
12688 && ! fixed_regs[12])
12690 move_bytes = (bytes > 32) ? 32 : bytes;
12691 gen_func.movmemsi = gen_movmemsi_8reg;
12693 else if (TARGET_STRING
12694 && bytes > 16 /* move up to 24 bytes at a time */
12700 && ! fixed_regs[10])
12702 move_bytes = (bytes > 24) ? 24 : bytes;
12703 gen_func.movmemsi = gen_movmemsi_6reg;
12705 else if (TARGET_STRING
12706 && bytes > 8 /* move up to 16 bytes at a time */
12710 && ! fixed_regs[8])
12712 move_bytes = (bytes > 16) ? 16 : bytes;
12713 gen_func.movmemsi = gen_movmemsi_4reg;
12715 else if (bytes >= 8 && TARGET_POWERPC64
12716 /* 64-bit loads and stores require word-aligned
12718 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12722 gen_func.mov = gen_movdi;
12724 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12725 { /* move up to 8 bytes at a time */
12726 move_bytes = (bytes > 8) ? 8 : bytes;
12727 gen_func.movmemsi = gen_movmemsi_2reg;
12729 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12730 { /* move 4 bytes */
12733 gen_func.mov = gen_movsi;
12735 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12736 { /* move 2 bytes */
12739 gen_func.mov = gen_movhi;
12741 else if (TARGET_STRING && bytes > 1)
12742 { /* move up to 4 bytes at a time */
12743 move_bytes = (bytes > 4) ? 4 : bytes;
12744 gen_func.movmemsi = gen_movmemsi_1reg;
12746 else /* move 1 byte at a time */
12750 gen_func.mov = gen_movqi;
12753 src = adjust_address (orig_src, mode, offset);
12754 dest = adjust_address (orig_dest, mode, offset);
12756 if (mode != BLKmode)
12758 rtx tmp_reg = gen_reg_rtx (mode);
12760 emit_insn ((*gen_func.mov) (tmp_reg, src));
12761 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12764 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12767 for (i = 0; i < num_reg; i++)
12768 emit_insn (stores[i]);
12772 if (mode == BLKmode)
12774 /* Move the address into scratch registers. The movmemsi
12775 patterns require zero offset. */
12776 if (!REG_P (XEXP (src, 0)))
12778 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12779 src = replace_equiv_address (src, src_reg);
12781 set_mem_size (src, GEN_INT (move_bytes));
12783 if (!REG_P (XEXP (dest, 0)))
12785 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12786 dest = replace_equiv_address (dest, dest_reg);
12788 set_mem_size (dest, GEN_INT (move_bytes));
12790 emit_insn ((*gen_func.movmemsi) (dest, src,
12791 GEN_INT (move_bytes & 31),
12800 /* Return a string to perform a load_multiple operation.
12801 operands[0] is the vector.
12802 operands[1] is the source address.
12803 operands[2] is the first destination register. */
12806 rs6000_output_load_multiple (rtx operands[3])
12808 /* We have to handle the case where the pseudo used to contain the address
12809 is assigned to one of the output registers. */
12811 int words = XVECLEN (operands[0], 0);
12814 if (XVECLEN (operands[0], 0) == 1)
12815 return "{l|lwz} %2,0(%1)";
12817 for (i = 0; i < words; i++)
12818 if (refers_to_regno_p (REGNO (operands[2]) + i,
12819 REGNO (operands[2]) + i + 1, operands[1], 0))
12823 xop[0] = GEN_INT (4 * (words-1));
12824 xop[1] = operands[1];
12825 xop[2] = operands[2];
12826 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12831 xop[0] = GEN_INT (4 * (words-1));
12832 xop[1] = operands[1];
12833 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12834 output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
12839 for (j = 0; j < words; j++)
12842 xop[0] = GEN_INT (j * 4);
12843 xop[1] = operands[1];
12844 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12845 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12847 xop[0] = GEN_INT (i * 4);
12848 xop[1] = operands[1];
12849 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12854 return "{lsi|lswi} %2,%1,%N0";
12858 /* A validation routine: say whether CODE, a condition code, and MODE
12859 match. The other alternatives either don't make sense or should
12860 never be generated. */
12863 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12865 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12866 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12867 && GET_MODE_CLASS (mode) == MODE_CC);
12869 /* These don't make sense. */
12870 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12871 || mode != CCUNSmode);
12873 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12874 || mode == CCUNSmode);
12876 gcc_assert (mode == CCFPmode
12877 || (code != ORDERED && code != UNORDERED
12878 && code != UNEQ && code != LTGT
12879 && code != UNGT && code != UNLT
12880 && code != UNGE && code != UNLE));
12882 /* These should never be generated except for
12883 flag_finite_math_only. */
12884 gcc_assert (mode != CCFPmode
12885 || flag_finite_math_only
12886 || (code != LE && code != GE
12887 && code != UNEQ && code != LTGT
12888 && code != UNGT && code != UNLT));
12890 /* These are invalid; the information is not there. */
12891 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12895 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12896 mask required to convert the result of a rotate insn into a shift
12897 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12900 includes_lshift_p (rtx shiftop, rtx andop)
12902 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12904 shift_mask <<= INTVAL (shiftop);
12906 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12909 /* Similar, but for right shift. */
12912 includes_rshift_p (rtx shiftop, rtx andop)
12914 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12916 shift_mask >>= INTVAL (shiftop);
12918 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12921 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12922 to perform a left shift. It must have exactly SHIFTOP least
12923 significant 0's, then one or more 1's, then zero or more 0's. */
12926 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12928 if (GET_CODE (andop) == CONST_INT)
12930 HOST_WIDE_INT c, lsb, shift_mask;
12932 c = INTVAL (andop);
12933 if (c == 0 || c == ~0)
12937 shift_mask <<= INTVAL (shiftop);
12939 /* Find the least significant one bit. */
12942 /* It must coincide with the LSB of the shift mask. */
12943 if (-lsb != shift_mask)
12946 /* Invert to look for the next transition (if any). */
12949 /* Remove the low group of ones (originally low group of zeros). */
12952 /* Again find the lsb, and check we have all 1's above. */
12956 else if (GET_CODE (andop) == CONST_DOUBLE
12957 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12959 HOST_WIDE_INT low, high, lsb;
12960 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12962 low = CONST_DOUBLE_LOW (andop);
12963 if (HOST_BITS_PER_WIDE_INT < 64)
12964 high = CONST_DOUBLE_HIGH (andop);
12966 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12967 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12970 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12972 shift_mask_high = ~0;
12973 if (INTVAL (shiftop) > 32)
12974 shift_mask_high <<= INTVAL (shiftop) - 32;
12976 lsb = high & -high;
12978 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12984 lsb = high & -high;
12985 return high == -lsb;
12988 shift_mask_low = ~0;
12989 shift_mask_low <<= INTVAL (shiftop);
12993 if (-lsb != shift_mask_low)
12996 if (HOST_BITS_PER_WIDE_INT < 64)
13001 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13003 lsb = high & -high;
13004 return high == -lsb;
13008 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13014 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13015 to perform a left shift. It must have SHIFTOP or more least
13016 significant 0's, with the remainder of the word 1's. */
13019 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13021 if (GET_CODE (andop) == CONST_INT)
13023 HOST_WIDE_INT c, lsb, shift_mask;
13026 shift_mask <<= INTVAL (shiftop);
13027 c = INTVAL (andop);
13029 /* Find the least significant one bit. */
13032 /* It must be covered by the shift mask.
13033 This test also rejects c == 0. */
13034 if ((lsb & shift_mask) == 0)
13037 /* Check we have all 1's above the transition, and reject all 1's. */
13038 return c == -lsb && lsb != 1;
13040 else if (GET_CODE (andop) == CONST_DOUBLE
13041 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13043 HOST_WIDE_INT low, lsb, shift_mask_low;
13045 low = CONST_DOUBLE_LOW (andop);
13047 if (HOST_BITS_PER_WIDE_INT < 64)
13049 HOST_WIDE_INT high, shift_mask_high;
13051 high = CONST_DOUBLE_HIGH (andop);
13055 shift_mask_high = ~0;
13056 if (INTVAL (shiftop) > 32)
13057 shift_mask_high <<= INTVAL (shiftop) - 32;
13059 lsb = high & -high;
13061 if ((lsb & shift_mask_high) == 0)
13064 return high == -lsb;
13070 shift_mask_low = ~0;
13071 shift_mask_low <<= INTVAL (shiftop);
13075 if ((lsb & shift_mask_low) == 0)
13078 return low == -lsb && lsb != 1;
13084 /* Return 1 if operands will generate a valid arguments to rlwimi
13085 instruction for insert with right shift in 64-bit mode. The mask may
13086 not start on the first bit or stop on the last bit because wrap-around
13087 effects of instruction do not correspond to semantics of RTL insn. */
13090 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13092 if (INTVAL (startop) > 32
13093 && INTVAL (startop) < 64
13094 && INTVAL (sizeop) > 1
13095 && INTVAL (sizeop) + INTVAL (startop) < 64
13096 && INTVAL (shiftop) > 0
13097 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13098 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13104 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13105 for lfq and stfq insns iff the registers are hard registers. */
13108 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13110 /* We might have been passed a SUBREG. */
13111 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13114 /* We might have been passed non floating point registers. */
13115 if (!FP_REGNO_P (REGNO (reg1))
13116 || !FP_REGNO_P (REGNO (reg2)))
13119 return (REGNO (reg1) == REGNO (reg2) - 1);
13122 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13123 addr1 and addr2 must be in consecutive memory locations
13124 (addr2 == addr1 + 8). */
13127 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13130 unsigned int reg1, reg2;
13131 int offset1, offset2;
13133 /* The mems cannot be volatile. */
13134 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13137 addr1 = XEXP (mem1, 0);
13138 addr2 = XEXP (mem2, 0);
13140 /* Extract an offset (if used) from the first addr. */
13141 if (GET_CODE (addr1) == PLUS)
13143 /* If not a REG, return zero. */
13144 if (GET_CODE (XEXP (addr1, 0)) != REG)
13148 reg1 = REGNO (XEXP (addr1, 0));
13149 /* The offset must be constant! */
13150 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13152 offset1 = INTVAL (XEXP (addr1, 1));
13155 else if (GET_CODE (addr1) != REG)
13159 reg1 = REGNO (addr1);
13160 /* This was a simple (mem (reg)) expression. Offset is 0. */
13164 /* And now for the second addr. */
13165 if (GET_CODE (addr2) == PLUS)
13167 /* If not a REG, return zero. */
13168 if (GET_CODE (XEXP (addr2, 0)) != REG)
13172 reg2 = REGNO (XEXP (addr2, 0));
13173 /* The offset must be constant. */
13174 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13176 offset2 = INTVAL (XEXP (addr2, 1));
13179 else if (GET_CODE (addr2) != REG)
13183 reg2 = REGNO (addr2);
13184 /* This was a simple (mem (reg)) expression. Offset is 0. */
13188 /* Both of these must have the same base register. */
13192 /* The offset for the second addr must be 8 more than the first addr. */
13193 if (offset2 != offset1 + 8)
13196 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13203 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13205 static bool eliminated = false;
13208 if (mode != SDmode)
13209 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13212 rtx mem = cfun->machine->sdmode_stack_slot;
13213 gcc_assert (mem != NULL_RTX);
13217 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13218 cfun->machine->sdmode_stack_slot = mem;
13224 if (TARGET_DEBUG_ADDR)
13226 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13227 GET_MODE_NAME (mode));
13229 fprintf (stderr, "\tNULL_RTX\n");
13238 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13240 /* Don't walk into types. */
13241 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13243 *walk_subtrees = 0;
13247 switch (TREE_CODE (*tp))
13256 case ALIGN_INDIRECT_REF:
13257 case MISALIGNED_INDIRECT_REF:
13258 case VIEW_CONVERT_EXPR:
13259 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13269 enum reload_reg_type {
13271 VECTOR_REGISTER_TYPE,
13272 OTHER_REGISTER_TYPE
13275 static enum reload_reg_type
13276 rs6000_reload_register_type (enum reg_class rclass)
13282 return GPR_REGISTER_TYPE;
13287 return VECTOR_REGISTER_TYPE;
13290 return OTHER_REGISTER_TYPE;
13294 /* Inform reload about cases where moving X with a mode MODE to a register in
13295 RCLASS requires an extra scratch or immediate register. Return the class
13296 needed for the immediate register.
13298 For VSX and Altivec, we may need a register to convert sp+offset into
13301 static enum reg_class
13302 rs6000_secondary_reload (bool in_p,
13304 enum reg_class rclass,
13305 enum machine_mode mode,
13306 secondary_reload_info *sri)
13308 enum reg_class ret = ALL_REGS;
13309 enum insn_code icode;
13310 bool default_p = false;
13312 sri->icode = CODE_FOR_nothing;
13314 /* Convert vector loads and stores into gprs to use an additional base
13316 icode = rs6000_vector_reload[mode][in_p != false];
13317 if (icode != CODE_FOR_nothing)
13320 sri->icode = CODE_FOR_nothing;
13321 sri->extra_cost = 0;
13323 if (GET_CODE (x) == MEM)
13325 rtx addr = XEXP (x, 0);
13327 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13328 an extra register in that case, but it would need an extra
13329 register if the addressing is reg+reg or (reg+reg)&(-16). */
13330 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13332 if (!legitimate_indirect_address_p (addr, false)
13333 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13335 sri->icode = icode;
13336 /* account for splitting the loads, and converting the
13337 address from reg+reg to reg. */
13338 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13339 + ((GET_CODE (addr) == AND) ? 1 : 0));
13342 /* Loads to and stores from vector registers can only do reg+reg
13343 addressing. Altivec registers can also do (reg+reg)&(-16). */
13344 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13345 || rclass == FLOAT_REGS || rclass == NO_REGS)
13347 if (!VECTOR_MEM_ALTIVEC_P (mode)
13348 && GET_CODE (addr) == AND
13349 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13350 && INTVAL (XEXP (addr, 1)) == -16
13351 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13352 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13354 sri->icode = icode;
13355 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13358 else if (!legitimate_indirect_address_p (addr, false)
13359 && (rclass == NO_REGS
13360 || !legitimate_indexed_address_p (addr, false)))
13362 sri->icode = icode;
13363 sri->extra_cost = 1;
13366 icode = CODE_FOR_nothing;
13368 /* Any other loads, including to pseudo registers which haven't been
13369 assigned to a register yet, default to require a scratch
13373 sri->icode = icode;
13374 sri->extra_cost = 2;
13377 else if (REG_P (x))
13379 int regno = true_regnum (x);
13381 icode = CODE_FOR_nothing;
13382 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13386 enum reg_class xclass = REGNO_REG_CLASS (regno);
13387 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13388 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13390 /* If memory is needed, use default_secondary_reload to create the
13392 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13405 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13407 gcc_assert (ret != ALL_REGS);
13409 if (TARGET_DEBUG_ADDR)
13412 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13414 reg_class_names[ret],
13415 in_p ? "true" : "false",
13416 reg_class_names[rclass],
13417 GET_MODE_NAME (mode));
13420 fprintf (stderr, ", default secondary reload");
13422 if (sri->icode != CODE_FOR_nothing)
13423 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13424 insn_data[sri->icode].name, sri->extra_cost);
13426 fprintf (stderr, "\n");
13434 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13435 to SP+reg addressing. */
13438 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13440 int regno = true_regnum (reg);
13441 enum machine_mode mode = GET_MODE (reg);
13442 enum reg_class rclass;
13444 rtx and_op2 = NULL_RTX;
13447 rtx scratch_or_premodify = scratch;
13451 if (TARGET_DEBUG_ADDR)
13453 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13454 store_p ? "store" : "load");
13455 fprintf (stderr, "reg:\n");
13457 fprintf (stderr, "mem:\n");
13459 fprintf (stderr, "scratch:\n");
13460 debug_rtx (scratch);
13463 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13464 gcc_assert (GET_CODE (mem) == MEM);
13465 rclass = REGNO_REG_CLASS (regno);
13466 addr = XEXP (mem, 0);
13470 /* GPRs can handle reg + small constant, all other addresses need to use
13471 the scratch register. */
13474 if (GET_CODE (addr) == AND)
13476 and_op2 = XEXP (addr, 1);
13477 addr = XEXP (addr, 0);
13480 if (GET_CODE (addr) == PRE_MODIFY)
13482 scratch_or_premodify = XEXP (addr, 0);
13483 gcc_assert (REG_P (scratch_or_premodify));
13484 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13485 addr = XEXP (addr, 1);
13488 if (GET_CODE (addr) == PLUS
13489 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13490 || and_op2 != NULL_RTX))
13492 addr_op1 = XEXP (addr, 0);
13493 addr_op2 = XEXP (addr, 1);
13494 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13496 if (!REG_P (addr_op2)
13497 && (GET_CODE (addr_op2) != CONST_INT
13498 || !satisfies_constraint_I (addr_op2)))
13500 if (TARGET_DEBUG_ADDR)
13503 "\nMove plus addr to register %s, mode = %s: ",
13504 rs6000_reg_names[REGNO (scratch)],
13505 GET_MODE_NAME (mode));
13506 debug_rtx (addr_op2);
13508 rs6000_emit_move (scratch, addr_op2, Pmode);
13509 addr_op2 = scratch;
13512 emit_insn (gen_rtx_SET (VOIDmode,
13513 scratch_or_premodify,
13514 gen_rtx_PLUS (Pmode,
13518 addr = scratch_or_premodify;
13519 scratch_or_premodify = scratch;
13521 else if (!legitimate_indirect_address_p (addr, false)
13522 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13524 if (TARGET_DEBUG_ADDR)
13526 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13527 rs6000_reg_names[REGNO (scratch_or_premodify)],
13528 GET_MODE_NAME (mode));
13531 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13532 addr = scratch_or_premodify;
13533 scratch_or_premodify = scratch;
13537 /* Float/Altivec registers can only handle reg+reg addressing. Move
13538 other addresses into a scratch register. */
13543 /* With float regs, we need to handle the AND ourselves, since we can't
13544 use the Altivec instruction with an implicit AND -16. Allow scalar
13545 loads to float registers to use reg+offset even if VSX. */
13546 if (GET_CODE (addr) == AND
13547 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13548 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13549 || INTVAL (XEXP (addr, 1)) != -16
13550 || !VECTOR_MEM_ALTIVEC_P (mode)))
13552 and_op2 = XEXP (addr, 1);
13553 addr = XEXP (addr, 0);
13556 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13557 as the address later. */
13558 if (GET_CODE (addr) == PRE_MODIFY
13559 && (!VECTOR_MEM_VSX_P (mode)
13560 || and_op2 != NULL_RTX
13561 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13563 scratch_or_premodify = XEXP (addr, 0);
13564 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13566 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13567 addr = XEXP (addr, 1);
13570 if (legitimate_indirect_address_p (addr, false) /* reg */
13571 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13572 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13573 || (GET_CODE (addr) == AND /* Altivec memory */
13574 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13575 && INTVAL (XEXP (addr, 1)) == -16
13576 && VECTOR_MEM_ALTIVEC_P (mode))
13577 || (rclass == FLOAT_REGS /* legacy float mem */
13578 && GET_MODE_SIZE (mode) == 8
13579 && and_op2 == NULL_RTX
13580 && scratch_or_premodify == scratch
13581 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13584 else if (GET_CODE (addr) == PLUS)
13586 addr_op1 = XEXP (addr, 0);
13587 addr_op2 = XEXP (addr, 1);
13588 gcc_assert (REG_P (addr_op1));
13590 if (TARGET_DEBUG_ADDR)
13592 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13593 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13594 debug_rtx (addr_op2);
13596 rs6000_emit_move (scratch, addr_op2, Pmode);
13597 emit_insn (gen_rtx_SET (VOIDmode,
13598 scratch_or_premodify,
13599 gen_rtx_PLUS (Pmode,
13602 addr = scratch_or_premodify;
13603 scratch_or_premodify = scratch;
13606 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13607 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13609 if (TARGET_DEBUG_ADDR)
13611 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13612 rs6000_reg_names[REGNO (scratch_or_premodify)],
13613 GET_MODE_NAME (mode));
13617 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13618 addr = scratch_or_premodify;
13619 scratch_or_premodify = scratch;
13623 gcc_unreachable ();
13628 gcc_unreachable ();
13631 /* If the original address involved a pre-modify that we couldn't use the VSX
13632 memory instruction with update, and we haven't taken care of already,
13633 store the address in the pre-modify register and use that as the
13635 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13637 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13638 addr = scratch_or_premodify;
13641 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13642 memory instruction, recreate the AND now, including the clobber which is
13643 generated by the general ANDSI3/ANDDI3 patterns for the
13644 andi. instruction. */
13645 if (and_op2 != NULL_RTX)
13647 if (! legitimate_indirect_address_p (addr, false))
13649 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13653 if (TARGET_DEBUG_ADDR)
13655 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13656 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13657 debug_rtx (and_op2);
13660 and_rtx = gen_rtx_SET (VOIDmode,
13662 gen_rtx_AND (Pmode,
13666 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13667 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13668 gen_rtvec (2, and_rtx, cc_clobber)));
13672 /* Adjust the address if it changed. */
13673 if (addr != XEXP (mem, 0))
13675 mem = change_address (mem, mode, addr);
13676 if (TARGET_DEBUG_ADDR)
13677 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13680 /* Now create the move. */
13682 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13684 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13689 /* Target hook to return the cover classes for Integrated Register Allocator.
13690 Cover classes is a set of non-intersected register classes covering all hard
13691 registers used for register allocation purpose. Any move between two
13692 registers of a cover class should be cheaper than load or store of the
13693 registers. The value is array of register classes with LIM_REG_CLASSES used
13696 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13697 account for the Altivec and Floating registers being subsets of the VSX
13698 register set under VSX, but distinct register sets on pre-VSX machines. */
13700 static const enum reg_class *
13701 rs6000_ira_cover_classes (void)
13703 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13704 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13706 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13709 /* Allocate a 64-bit stack slot to be used for copying SDmode
13710 values through if this function has any SDmode references. */
13713 rs6000_alloc_sdmode_stack_slot (void)
13717 gimple_stmt_iterator gsi;
13719 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13722 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13724 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13727 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13728 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13734 /* Check for any SDmode parameters of the function. */
13735 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13737 if (TREE_TYPE (t) == error_mark_node)
13740 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13741 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13743 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13744 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13752 rs6000_instantiate_decls (void)
13754 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13755 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13758 /* Given an rtx X being reloaded into a reg required to be
13759 in class CLASS, return the class of reg to actually use.
13760 In general this is just CLASS; but on some machines
13761 in some cases it is preferable to use a more restrictive class.
13763 On the RS/6000, we have to return NO_REGS when we want to reload a
13764 floating-point CONST_DOUBLE to force it to be copied to memory.
13766 We also don't want to reload integer values into floating-point
13767 registers if we can at all help it. In fact, this can
13768 cause reload to die, if it tries to generate a reload of CTR
13769 into a FP register and discovers it doesn't have the memory location
13772 ??? Would it be a good idea to have reload do the converse, that is
13773 try to reload floating modes into FP registers if possible?
13776 static enum reg_class
13777 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13779 enum machine_mode mode = GET_MODE (x);
13781 if (VECTOR_UNIT_VSX_P (mode)
13782 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13785 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13786 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13787 && easy_vector_constant (x, mode))
13788 return ALTIVEC_REGS;
13790 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13793 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13794 return GENERAL_REGS;
13796 /* For VSX, prefer the traditional registers for DF if the address is of the
13797 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13798 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13800 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13802 if (mode == DFmode && GET_CODE (x) == MEM)
13804 rtx addr = XEXP (x, 0);
13806 if (legitimate_indirect_address_p (addr, false)) /* reg */
13809 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13812 if (GET_CODE (addr) == PRE_MODIFY
13813 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13819 if (VECTOR_UNIT_ALTIVEC_P (mode))
13820 return ALTIVEC_REGS;
13828 /* Debug version of rs6000_preferred_reload_class. */
13829 static enum reg_class
13830 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13832 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13835 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13837 reg_class_names[ret], reg_class_names[rclass],
13838 GET_MODE_NAME (GET_MODE (x)));
13844 /* If we are copying between FP or AltiVec registers and anything else, we need
13845 a memory location. The exception is when we are targeting ppc64 and the
13846 move to/from fpr to gpr instructions are available. Also, under VSX, you
13847 can copy vector registers from the FP register set to the Altivec register
13848 set and vice versa. */
13851 rs6000_secondary_memory_needed (enum reg_class class1,
13852 enum reg_class class2,
13853 enum machine_mode mode)
13855 if (class1 == class2)
13858 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13859 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13860 between these classes. But we need memory for other things that can go in
13861 FLOAT_REGS like SFmode. */
13863 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13864 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13865 || class1 == FLOAT_REGS))
13866 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13867 && class2 != FLOAT_REGS);
13869 if (class1 == VSX_REGS || class2 == VSX_REGS)
13872 if (class1 == FLOAT_REGS
13873 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13874 || ((mode != DFmode)
13875 && (mode != DDmode)
13876 && (mode != DImode))))
13879 if (class2 == FLOAT_REGS
13880 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13881 || ((mode != DFmode)
13882 && (mode != DDmode)
13883 && (mode != DImode))))
13886 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13892 /* Debug version of rs6000_secondary_memory_needed. */
13894 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13895 enum reg_class class2,
13896 enum machine_mode mode)
13898 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13901 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13902 "class2 = %s, mode = %s\n",
13903 ret ? "true" : "false", reg_class_names[class1],
13904 reg_class_names[class2], GET_MODE_NAME (mode));
13909 /* Return the register class of a scratch register needed to copy IN into
13910 or out of a register in RCLASS in MODE. If it can be done directly,
13911 NO_REGS is returned. */
13913 static enum reg_class
13914 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13919 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13921 && MACHOPIC_INDIRECT
13925 /* We cannot copy a symbolic operand directly into anything
13926 other than BASE_REGS for TARGET_ELF. So indicate that a
13927 register from BASE_REGS is needed as an intermediate
13930 On Darwin, pic addresses require a load from memory, which
13931 needs a base register. */
13932 if (rclass != BASE_REGS
13933 && (GET_CODE (in) == SYMBOL_REF
13934 || GET_CODE (in) == HIGH
13935 || GET_CODE (in) == LABEL_REF
13936 || GET_CODE (in) == CONST))
13940 if (GET_CODE (in) == REG)
13942 regno = REGNO (in);
13943 if (regno >= FIRST_PSEUDO_REGISTER)
13945 regno = true_regnum (in);
13946 if (regno >= FIRST_PSEUDO_REGISTER)
13950 else if (GET_CODE (in) == SUBREG)
13952 regno = true_regnum (in);
13953 if (regno >= FIRST_PSEUDO_REGISTER)
13959 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13961 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13962 || (regno >= 0 && INT_REGNO_P (regno)))
13965 /* Constants, memory, and FP registers can go into FP registers. */
13966 if ((regno == -1 || FP_REGNO_P (regno))
13967 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13968 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13970 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13973 && (regno == -1 || VSX_REGNO_P (regno))
13974 && VSX_REG_CLASS_P (rclass))
13977 /* Memory, and AltiVec registers can go into AltiVec registers. */
13978 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13979 && rclass == ALTIVEC_REGS)
13982 /* We can copy among the CR registers. */
13983 if ((rclass == CR_REGS || rclass == CR0_REGS)
13984 && regno >= 0 && CR_REGNO_P (regno))
13987 /* Otherwise, we need GENERAL_REGS. */
13988 return GENERAL_REGS;
13991 /* Debug version of rs6000_secondary_reload_class. */
13992 static enum reg_class
13993 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13994 enum machine_mode mode, rtx in)
13996 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13998 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13999 "mode = %s, input rtx:\n",
14000 reg_class_names[ret], reg_class_names[rclass],
14001 GET_MODE_NAME (mode));
14007 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14010 rs6000_cannot_change_mode_class (enum machine_mode from,
14011 enum machine_mode to,
14012 enum reg_class rclass)
14014 unsigned from_size = GET_MODE_SIZE (from);
14015 unsigned to_size = GET_MODE_SIZE (to);
14017 if (from_size != to_size)
14019 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14020 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14021 && reg_classes_intersect_p (xclass, rclass));
14024 if (TARGET_E500_DOUBLE
14025 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14026 || (((to) == TFmode) + ((from) == TFmode)) == 1
14027 || (((to) == DDmode) + ((from) == DDmode)) == 1
14028 || (((to) == TDmode) + ((from) == TDmode)) == 1
14029 || (((to) == DImode) + ((from) == DImode)) == 1))
14032 /* Since the VSX register set includes traditional floating point registers
14033 and altivec registers, just check for the size being different instead of
14034 trying to check whether the modes are vector modes. Otherwise it won't
14035 allow say DF and DI to change classes. */
14036 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14037 return (from_size != 8 && from_size != 16);
14039 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14040 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14043 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14044 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14050 /* Debug version of rs6000_cannot_change_mode_class. */
14052 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14053 enum machine_mode to,
14054 enum reg_class rclass)
14056 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14059 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14060 "to = %s, rclass = %s\n",
14061 ret ? "true" : "false",
14062 GET_MODE_NAME (from), GET_MODE_NAME (to),
14063 reg_class_names[rclass]);
14068 /* Given a comparison operation, return the bit number in CCR to test. We
14069 know this is a valid comparison.
14071 SCC_P is 1 if this is for an scc. That means that %D will have been
14072 used instead of %C, so the bits will be in different places.
14074 Return -1 if OP isn't a valid comparison for some reason. */
14077 ccr_bit (rtx op, int scc_p)
14079 enum rtx_code code = GET_CODE (op);
14080 enum machine_mode cc_mode;
14085 if (!COMPARISON_P (op))
14088 reg = XEXP (op, 0);
14090 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14092 cc_mode = GET_MODE (reg);
14093 cc_regnum = REGNO (reg);
14094 base_bit = 4 * (cc_regnum - CR0_REGNO);
14096 validate_condition_mode (code, cc_mode);
14098 /* When generating a sCOND operation, only positive conditions are
14101 || code == EQ || code == GT || code == LT || code == UNORDERED
14102 || code == GTU || code == LTU);
14107 return scc_p ? base_bit + 3 : base_bit + 2;
14109 return base_bit + 2;
14110 case GT: case GTU: case UNLE:
14111 return base_bit + 1;
14112 case LT: case LTU: case UNGE:
14114 case ORDERED: case UNORDERED:
14115 return base_bit + 3;
14118 /* If scc, we will have done a cror to put the bit in the
14119 unordered position. So test that bit. For integer, this is ! LT
14120 unless this is an scc insn. */
14121 return scc_p ? base_bit + 3 : base_bit;
14124 return scc_p ? base_bit + 3 : base_bit + 1;
14127 gcc_unreachable ();
14131 /* Return the GOT register. */
14134 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14136 /* The second flow pass currently (June 1999) can't update
14137 regs_ever_live without disturbing other parts of the compiler, so
14138 update it here to make the prolog/epilogue code happy. */
14139 if (!can_create_pseudo_p ()
14140 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14141 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14143 crtl->uses_pic_offset_table = 1;
14145 return pic_offset_table_rtx;
14148 /* Function to init struct machine_function.
14149 This will be called, via a pointer variable,
14150 from push_function_context. */
14152 static struct machine_function *
14153 rs6000_init_machine_status (void)
14155 return GGC_CNEW (machine_function);
14158 /* These macros test for integers and extract the low-order bits. */
14160 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14161 && GET_MODE (X) == VOIDmode)
14163 #define INT_LOWPART(X) \
14164 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14167 extract_MB (rtx op)
14170 unsigned long val = INT_LOWPART (op);
14172 /* If the high bit is zero, the value is the first 1 bit we find
14174 if ((val & 0x80000000) == 0)
14176 gcc_assert (val & 0xffffffff);
14179 while (((val <<= 1) & 0x80000000) == 0)
14184 /* If the high bit is set and the low bit is not, or the mask is all
14185 1's, the value is zero. */
14186 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14189 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14192 while (((val >>= 1) & 1) != 0)
14199 extract_ME (rtx op)
14202 unsigned long val = INT_LOWPART (op);
14204 /* If the low bit is zero, the value is the first 1 bit we find from
14206 if ((val & 1) == 0)
14208 gcc_assert (val & 0xffffffff);
14211 while (((val >>= 1) & 1) == 0)
14217 /* If the low bit is set and the high bit is not, or the mask is all
14218 1's, the value is 31. */
14219 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14222 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14225 while (((val <<= 1) & 0x80000000) != 0)
14231 /* Locate some local-dynamic symbol still in use by this function
14232 so that we can print its name in some tls_ld pattern. */
14234 static const char *
14235 rs6000_get_some_local_dynamic_name (void)
14239 if (cfun->machine->some_ld_name)
14240 return cfun->machine->some_ld_name;
14242 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14244 && for_each_rtx (&PATTERN (insn),
14245 rs6000_get_some_local_dynamic_name_1, 0))
14246 return cfun->machine->some_ld_name;
14248 gcc_unreachable ();
14251 /* Helper function for rs6000_get_some_local_dynamic_name. */
14254 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14258 if (GET_CODE (x) == SYMBOL_REF)
14260 const char *str = XSTR (x, 0);
14261 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14263 cfun->machine->some_ld_name = str;
14271 /* Write out a function code label. */
14274 rs6000_output_function_entry (FILE *file, const char *fname)
14276 if (fname[0] != '.')
14278 switch (DEFAULT_ABI)
14281 gcc_unreachable ();
14287 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14296 RS6000_OUTPUT_BASENAME (file, fname);
14298 assemble_name (file, fname);
14301 /* Print an operand. Recognize special options, documented below. */
14304 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14305 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14307 #define SMALL_DATA_RELOC "sda21"
14308 #define SMALL_DATA_REG 0
14312 print_operand (FILE *file, rtx x, int code)
14316 unsigned HOST_WIDE_INT uval;
14321 /* Write out an instruction after the call which may be replaced
14322 with glue code by the loader. This depends on the AIX version. */
14323 asm_fprintf (file, RS6000_CALL_GLUE);
14326 /* %a is output_address. */
14329 /* If X is a constant integer whose low-order 5 bits are zero,
14330 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14331 in the AIX assembler where "sri" with a zero shift count
14332 writes a trash instruction. */
14333 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14340 /* If constant, low-order 16 bits of constant, unsigned.
14341 Otherwise, write normally. */
14343 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14345 print_operand (file, x, 0);
14349 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14350 for 64-bit mask direction. */
14351 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14354 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14358 /* X is a CR register. Print the number of the GT bit of the CR. */
14359 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14360 output_operand_lossage ("invalid %%c value");
14362 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14366 /* Like 'J' but get to the GT bit only. */
14367 gcc_assert (GET_CODE (x) == REG);
14369 /* Bit 1 is GT bit. */
14370 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14372 /* Add one for shift count in rlinm for scc. */
14373 fprintf (file, "%d", i + 1);
14377 /* X is a CR register. Print the number of the EQ bit of the CR */
14378 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14379 output_operand_lossage ("invalid %%E value");
14381 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14385 /* X is a CR register. Print the shift count needed to move it
14386 to the high-order four bits. */
14387 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14388 output_operand_lossage ("invalid %%f value");
14390 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14394 /* Similar, but print the count for the rotate in the opposite
14396 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14397 output_operand_lossage ("invalid %%F value");
14399 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14403 /* X is a constant integer. If it is negative, print "m",
14404 otherwise print "z". This is to make an aze or ame insn. */
14405 if (GET_CODE (x) != CONST_INT)
14406 output_operand_lossage ("invalid %%G value");
14407 else if (INTVAL (x) >= 0)
14414 /* If constant, output low-order five bits. Otherwise, write
14417 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14419 print_operand (file, x, 0);
14423 /* If constant, output low-order six bits. Otherwise, write
14426 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14428 print_operand (file, x, 0);
14432 /* Print `i' if this is a constant, else nothing. */
14438 /* Write the bit number in CCR for jump. */
14439 i = ccr_bit (x, 0);
14441 output_operand_lossage ("invalid %%j code");
14443 fprintf (file, "%d", i);
14447 /* Similar, but add one for shift count in rlinm for scc and pass
14448 scc flag to `ccr_bit'. */
14449 i = ccr_bit (x, 1);
14451 output_operand_lossage ("invalid %%J code");
14453 /* If we want bit 31, write a shift count of zero, not 32. */
14454 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14458 /* X must be a constant. Write the 1's complement of the
14461 output_operand_lossage ("invalid %%k value");
14463 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14467 /* X must be a symbolic constant on ELF. Write an
14468 expression suitable for an 'addi' that adds in the low 16
14469 bits of the MEM. */
14470 if (GET_CODE (x) != CONST)
14472 print_operand_address (file, x);
14473 fputs ("@l", file);
14477 if (GET_CODE (XEXP (x, 0)) != PLUS
14478 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14479 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14480 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14481 output_operand_lossage ("invalid %%K value");
14482 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14483 fputs ("@l", file);
14484 /* For GNU as, there must be a non-alphanumeric character
14485 between 'l' and the number. The '-' is added by
14486 print_operand() already. */
14487 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14489 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14493 /* %l is output_asm_label. */
14496 /* Write second word of DImode or DFmode reference. Works on register
14497 or non-indexed memory only. */
14498 if (GET_CODE (x) == REG)
14499 fputs (reg_names[REGNO (x) + 1], file);
14500 else if (GET_CODE (x) == MEM)
14502 /* Handle possible auto-increment. Since it is pre-increment and
14503 we have already done it, we can just use an offset of word. */
14504 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14505 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14506 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14508 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14509 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14512 output_address (XEXP (adjust_address_nv (x, SImode,
14516 if (small_data_operand (x, GET_MODE (x)))
14517 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14518 reg_names[SMALL_DATA_REG]);
14523 /* MB value for a mask operand. */
14524 if (! mask_operand (x, SImode))
14525 output_operand_lossage ("invalid %%m value");
14527 fprintf (file, "%d", extract_MB (x));
14531 /* ME value for a mask operand. */
14532 if (! mask_operand (x, SImode))
14533 output_operand_lossage ("invalid %%M value");
14535 fprintf (file, "%d", extract_ME (x));
14538 /* %n outputs the negative of its operand. */
14541 /* Write the number of elements in the vector times 4. */
14542 if (GET_CODE (x) != PARALLEL)
14543 output_operand_lossage ("invalid %%N value");
14545 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14549 /* Similar, but subtract 1 first. */
14550 if (GET_CODE (x) != PARALLEL)
14551 output_operand_lossage ("invalid %%O value");
14553 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14557 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14559 || INT_LOWPART (x) < 0
14560 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14561 output_operand_lossage ("invalid %%p value");
14563 fprintf (file, "%d", i);
14567 /* The operand must be an indirect memory reference. The result
14568 is the register name. */
14569 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14570 || REGNO (XEXP (x, 0)) >= 32)
14571 output_operand_lossage ("invalid %%P value");
14573 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14577 /* This outputs the logical code corresponding to a boolean
14578 expression. The expression may have one or both operands
14579 negated (if one, only the first one). For condition register
14580 logical operations, it will also treat the negated
14581 CR codes as NOTs, but not handle NOTs of them. */
14583 const char *const *t = 0;
14585 enum rtx_code code = GET_CODE (x);
14586 static const char * const tbl[3][3] = {
14587 { "and", "andc", "nor" },
14588 { "or", "orc", "nand" },
14589 { "xor", "eqv", "xor" } };
14593 else if (code == IOR)
14595 else if (code == XOR)
14598 output_operand_lossage ("invalid %%q value");
14600 if (GET_CODE (XEXP (x, 0)) != NOT)
14604 if (GET_CODE (XEXP (x, 1)) == NOT)
14622 /* X is a CR register. Print the mask for `mtcrf'. */
14623 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14624 output_operand_lossage ("invalid %%R value");
14626 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14630 /* Low 5 bits of 32 - value */
14632 output_operand_lossage ("invalid %%s value");
14634 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14638 /* PowerPC64 mask position. All 0's is excluded.
14639 CONST_INT 32-bit mask is considered sign-extended so any
14640 transition must occur within the CONST_INT, not on the boundary. */
14641 if (! mask64_operand (x, DImode))
14642 output_operand_lossage ("invalid %%S value");
14644 uval = INT_LOWPART (x);
14646 if (uval & 1) /* Clear Left */
14648 #if HOST_BITS_PER_WIDE_INT > 64
14649 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14653 else /* Clear Right */
14656 #if HOST_BITS_PER_WIDE_INT > 64
14657 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14663 gcc_assert (i >= 0);
14664 fprintf (file, "%d", i);
14668 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14669 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14671 /* Bit 3 is OV bit. */
14672 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14674 /* If we want bit 31, write a shift count of zero, not 32. */
14675 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14679 /* Print the symbolic name of a branch target register. */
14680 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14681 && REGNO (x) != CTR_REGNO))
14682 output_operand_lossage ("invalid %%T value");
14683 else if (REGNO (x) == LR_REGNO)
14684 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14686 fputs ("ctr", file);
14690 /* High-order 16 bits of constant for use in unsigned operand. */
14692 output_operand_lossage ("invalid %%u value");
14694 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14695 (INT_LOWPART (x) >> 16) & 0xffff);
14699 /* High-order 16 bits of constant for use in signed operand. */
14701 output_operand_lossage ("invalid %%v value");
14703 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14704 (INT_LOWPART (x) >> 16) & 0xffff);
14708 /* Print `u' if this has an auto-increment or auto-decrement. */
14709 if (GET_CODE (x) == MEM
14710 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14711 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14712 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14717 /* Print the trap code for this operand. */
14718 switch (GET_CODE (x))
14721 fputs ("eq", file); /* 4 */
14724 fputs ("ne", file); /* 24 */
14727 fputs ("lt", file); /* 16 */
14730 fputs ("le", file); /* 20 */
14733 fputs ("gt", file); /* 8 */
14736 fputs ("ge", file); /* 12 */
14739 fputs ("llt", file); /* 2 */
14742 fputs ("lle", file); /* 6 */
14745 fputs ("lgt", file); /* 1 */
14748 fputs ("lge", file); /* 5 */
14751 gcc_unreachable ();
14756 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14759 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14760 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14762 print_operand (file, x, 0);
14766 /* MB value for a PowerPC64 rldic operand. */
14767 val = (GET_CODE (x) == CONST_INT
14768 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14773 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14774 if ((val <<= 1) < 0)
14777 #if HOST_BITS_PER_WIDE_INT == 32
14778 if (GET_CODE (x) == CONST_INT && i >= 0)
14779 i += 32; /* zero-extend high-part was all 0's */
14780 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14782 val = CONST_DOUBLE_LOW (x);
14788 for ( ; i < 64; i++)
14789 if ((val <<= 1) < 0)
14794 fprintf (file, "%d", i + 1);
14798 /* X is a FPR or Altivec register used in a VSX context. */
14799 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14800 output_operand_lossage ("invalid %%x value");
14803 int reg = REGNO (x);
14804 int vsx_reg = (FP_REGNO_P (reg)
14806 : reg - FIRST_ALTIVEC_REGNO + 32);
14808 #ifdef TARGET_REGNAMES
14809 if (TARGET_REGNAMES)
14810 fprintf (file, "%%vs%d", vsx_reg);
14813 fprintf (file, "%d", vsx_reg);
14818 if (GET_CODE (x) == MEM
14819 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14820 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14821 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14826 /* Like 'L', for third word of TImode */
14827 if (GET_CODE (x) == REG)
14828 fputs (reg_names[REGNO (x) + 2], file);
14829 else if (GET_CODE (x) == MEM)
14831 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14832 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14833 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14834 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14835 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14837 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14838 if (small_data_operand (x, GET_MODE (x)))
14839 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14840 reg_names[SMALL_DATA_REG]);
14845 /* X is a SYMBOL_REF. Write out the name preceded by a
14846 period and without any trailing data in brackets. Used for function
14847 names. If we are configured for System V (or the embedded ABI) on
14848 the PowerPC, do not emit the period, since those systems do not use
14849 TOCs and the like. */
14850 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14852 /* Mark the decl as referenced so that cgraph will output the
14854 if (SYMBOL_REF_DECL (x))
14855 mark_decl_referenced (SYMBOL_REF_DECL (x));
14857 /* For macho, check to see if we need a stub. */
14860 const char *name = XSTR (x, 0);
14862 if (MACHOPIC_INDIRECT
14863 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14864 name = machopic_indirection_name (x, /*stub_p=*/true);
14866 assemble_name (file, name);
14868 else if (!DOT_SYMBOLS)
14869 assemble_name (file, XSTR (x, 0));
14871 rs6000_output_function_entry (file, XSTR (x, 0));
14875 /* Like 'L', for last word of TImode. */
14876 if (GET_CODE (x) == REG)
14877 fputs (reg_names[REGNO (x) + 3], file);
14878 else if (GET_CODE (x) == MEM)
14880 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14881 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14882 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14883 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14884 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14886 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14887 if (small_data_operand (x, GET_MODE (x)))
14888 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14889 reg_names[SMALL_DATA_REG]);
14893 /* Print AltiVec or SPE memory operand. */
14898 gcc_assert (GET_CODE (x) == MEM);
14902 /* Ugly hack because %y is overloaded. */
14903 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14904 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14905 || GET_MODE (x) == TFmode
14906 || GET_MODE (x) == TImode))
14908 /* Handle [reg]. */
14909 if (GET_CODE (tmp) == REG)
14911 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14914 /* Handle [reg+UIMM]. */
14915 else if (GET_CODE (tmp) == PLUS &&
14916 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14920 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14922 x = INTVAL (XEXP (tmp, 1));
14923 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14927 /* Fall through. Must be [reg+reg]. */
14929 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14930 && GET_CODE (tmp) == AND
14931 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14932 && INTVAL (XEXP (tmp, 1)) == -16)
14933 tmp = XEXP (tmp, 0);
14934 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14935 && GET_CODE (tmp) == PRE_MODIFY)
14936 tmp = XEXP (tmp, 1);
14937 if (GET_CODE (tmp) == REG)
14938 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14941 if (!GET_CODE (tmp) == PLUS
14942 || !REG_P (XEXP (tmp, 0))
14943 || !REG_P (XEXP (tmp, 1)))
14945 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14949 if (REGNO (XEXP (tmp, 0)) == 0)
14950 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14951 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14953 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14954 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14960 if (GET_CODE (x) == REG)
14961 fprintf (file, "%s", reg_names[REGNO (x)]);
14962 else if (GET_CODE (x) == MEM)
14964 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14965 know the width from the mode. */
14966 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14967 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14968 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14969 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14970 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14971 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14972 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14973 output_address (XEXP (XEXP (x, 0), 1));
14975 output_address (XEXP (x, 0));
14978 output_addr_const (file, x);
14982 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14986 output_operand_lossage ("invalid %%xn code");
14990 /* Print the address of an operand. */
14993 print_operand_address (FILE *file, rtx x)
14995 if (GET_CODE (x) == REG)
14996 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14997 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14998 || GET_CODE (x) == LABEL_REF)
15000 output_addr_const (file, x);
15001 if (small_data_operand (x, GET_MODE (x)))
15002 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15003 reg_names[SMALL_DATA_REG]);
15005 gcc_assert (!TARGET_TOC);
15007 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15009 gcc_assert (REG_P (XEXP (x, 0)));
15010 if (REGNO (XEXP (x, 0)) == 0)
15011 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15012 reg_names[ REGNO (XEXP (x, 0)) ]);
15014 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15015 reg_names[ REGNO (XEXP (x, 1)) ]);
15017 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15018 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15019 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15021 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15022 && CONSTANT_P (XEXP (x, 1)))
15024 output_addr_const (file, XEXP (x, 1));
15025 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15029 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15030 && CONSTANT_P (XEXP (x, 1)))
15032 fprintf (file, "lo16(");
15033 output_addr_const (file, XEXP (x, 1));
15034 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15037 else if (legitimate_constant_pool_address_p (x))
15039 output_addr_const (file, XEXP (x, 1));
15040 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15043 gcc_unreachable ();
15046 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15049 rs6000_output_addr_const_extra (FILE *file, rtx x)
15051 if (GET_CODE (x) == UNSPEC)
15052 switch (XINT (x, 1))
15054 case UNSPEC_TOCREL:
15055 x = XVECEXP (x, 0, 0);
15056 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15057 output_addr_const (file, x);
15058 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15061 assemble_name (file, toc_label_name);
15063 else if (TARGET_ELF)
15064 fputs ("@toc", file);
15068 case UNSPEC_MACHOPIC_OFFSET:
15069 output_addr_const (file, XVECEXP (x, 0, 0));
15071 machopic_output_function_base_name (file);
15078 /* Target hook for assembling integer objects. The PowerPC version has
15079 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15080 is defined. It also needs to handle DI-mode objects on 64-bit
15084 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15086 #ifdef RELOCATABLE_NEEDS_FIXUP
15087 /* Special handling for SI values. */
15088 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15090 static int recurse = 0;
15092 /* For -mrelocatable, we mark all addresses that need to be fixed up
15093 in the .fixup section. */
15094 if (TARGET_RELOCATABLE
15095 && in_section != toc_section
15096 && in_section != text_section
15097 && !unlikely_text_section_p (in_section)
15099 && GET_CODE (x) != CONST_INT
15100 && GET_CODE (x) != CONST_DOUBLE
15106 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15108 ASM_OUTPUT_LABEL (asm_out_file, buf);
15109 fprintf (asm_out_file, "\t.long\t(");
15110 output_addr_const (asm_out_file, x);
15111 fprintf (asm_out_file, ")@fixup\n");
15112 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15113 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15114 fprintf (asm_out_file, "\t.long\t");
15115 assemble_name (asm_out_file, buf);
15116 fprintf (asm_out_file, "\n\t.previous\n");
15120 /* Remove initial .'s to turn a -mcall-aixdesc function
15121 address into the address of the descriptor, not the function
15123 else if (GET_CODE (x) == SYMBOL_REF
15124 && XSTR (x, 0)[0] == '.'
15125 && DEFAULT_ABI == ABI_AIX)
15127 const char *name = XSTR (x, 0);
15128 while (*name == '.')
15131 fprintf (asm_out_file, "\t.long\t%s\n", name);
15135 #endif /* RELOCATABLE_NEEDS_FIXUP */
15136 return default_assemble_integer (x, size, aligned_p);
15139 #ifdef HAVE_GAS_HIDDEN
15140 /* Emit an assembler directive to set symbol visibility for DECL to
15141 VISIBILITY_TYPE. */
15144 rs6000_assemble_visibility (tree decl, int vis)
15146 /* Functions need to have their entry point symbol visibility set as
15147 well as their descriptor symbol visibility. */
15148 if (DEFAULT_ABI == ABI_AIX
15150 && TREE_CODE (decl) == FUNCTION_DECL)
15152 static const char * const visibility_types[] = {
15153 NULL, "internal", "hidden", "protected"
15156 const char *name, *type;
15158 name = ((* targetm.strip_name_encoding)
15159 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15160 type = visibility_types[vis];
15162 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15163 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15166 default_assemble_visibility (decl, vis);
15171 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15173 /* Reversal of FP compares takes care -- an ordered compare
15174 becomes an unordered compare and vice versa. */
15175 if (mode == CCFPmode
15176 && (!flag_finite_math_only
15177 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15178 || code == UNEQ || code == LTGT))
15179 return reverse_condition_maybe_unordered (code);
15181 return reverse_condition (code);
15184 /* Generate a compare for CODE. Return a brand-new rtx that
15185 represents the result of the compare. */
15188 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15190 enum machine_mode comp_mode;
15191 rtx compare_result;
15192 enum rtx_code code = GET_CODE (cmp);
15193 rtx op0 = XEXP (cmp, 0);
15194 rtx op1 = XEXP (cmp, 1);
15196 if (FLOAT_MODE_P (mode))
15197 comp_mode = CCFPmode;
15198 else if (code == GTU || code == LTU
15199 || code == GEU || code == LEU)
15200 comp_mode = CCUNSmode;
15201 else if ((code == EQ || code == NE)
15202 && GET_CODE (op0) == SUBREG
15203 && GET_CODE (op1) == SUBREG
15204 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15205 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15206 /* These are unsigned values, perhaps there will be a later
15207 ordering compare that can be shared with this one.
15208 Unfortunately we cannot detect the signedness of the operands
15209 for non-subregs. */
15210 comp_mode = CCUNSmode;
15212 comp_mode = CCmode;
15214 /* First, the compare. */
15215 compare_result = gen_reg_rtx (comp_mode);
15217 /* E500 FP compare instructions on the GPRs. Yuck! */
15218 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15219 && FLOAT_MODE_P (mode))
15221 rtx cmp, or_result, compare_result2;
15222 enum machine_mode op_mode = GET_MODE (op0);
15224 if (op_mode == VOIDmode)
15225 op_mode = GET_MODE (op1);
15227 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15228 This explains the following mess. */
15232 case EQ: case UNEQ: case NE: case LTGT:
15236 cmp = (flag_finite_math_only && !flag_trapping_math)
15237 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15238 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15242 cmp = (flag_finite_math_only && !flag_trapping_math)
15243 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15244 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15248 cmp = (flag_finite_math_only && !flag_trapping_math)
15249 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15250 : gen_cmptfeq_gpr (compare_result, op0, op1);
15254 gcc_unreachable ();
15258 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15262 cmp = (flag_finite_math_only && !flag_trapping_math)
15263 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15264 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15268 cmp = (flag_finite_math_only && !flag_trapping_math)
15269 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15270 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15274 cmp = (flag_finite_math_only && !flag_trapping_math)
15275 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15276 : gen_cmptfgt_gpr (compare_result, op0, op1);
15280 gcc_unreachable ();
15284 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15288 cmp = (flag_finite_math_only && !flag_trapping_math)
15289 ? gen_tstsflt_gpr (compare_result, op0, op1)
15290 : gen_cmpsflt_gpr (compare_result, op0, op1);
15294 cmp = (flag_finite_math_only && !flag_trapping_math)
15295 ? gen_tstdflt_gpr (compare_result, op0, op1)
15296 : gen_cmpdflt_gpr (compare_result, op0, op1);
15300 cmp = (flag_finite_math_only && !flag_trapping_math)
15301 ? gen_tsttflt_gpr (compare_result, op0, op1)
15302 : gen_cmptflt_gpr (compare_result, op0, op1);
15306 gcc_unreachable ();
15310 gcc_unreachable ();
15313 /* Synthesize LE and GE from LT/GT || EQ. */
15314 if (code == LE || code == GE || code == LEU || code == GEU)
15320 case LE: code = LT; break;
15321 case GE: code = GT; break;
15322 case LEU: code = LT; break;
15323 case GEU: code = GT; break;
15324 default: gcc_unreachable ();
15327 compare_result2 = gen_reg_rtx (CCFPmode);
15333 cmp = (flag_finite_math_only && !flag_trapping_math)
15334 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15335 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15339 cmp = (flag_finite_math_only && !flag_trapping_math)
15340 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15341 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15345 cmp = (flag_finite_math_only && !flag_trapping_math)
15346 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15347 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15351 gcc_unreachable ();
15355 /* OR them together. */
15356 or_result = gen_reg_rtx (CCFPmode);
15357 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15359 compare_result = or_result;
15364 if (code == NE || code == LTGT)
15374 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15375 CLOBBERs to match cmptf_internal2 pattern. */
15376 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15377 && GET_MODE (op0) == TFmode
15378 && !TARGET_IEEEQUAD
15379 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15380 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15382 gen_rtx_SET (VOIDmode,
15384 gen_rtx_COMPARE (comp_mode, op0, op1)),
15385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15386 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15387 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15388 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15390 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15391 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15392 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15393 else if (GET_CODE (op1) == UNSPEC
15394 && XINT (op1, 1) == UNSPEC_SP_TEST)
15396 rtx op1b = XVECEXP (op1, 0, 0);
15397 comp_mode = CCEQmode;
15398 compare_result = gen_reg_rtx (CCEQmode);
15400 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15402 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15405 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15406 gen_rtx_COMPARE (comp_mode, op0, op1)));
15409 /* Some kinds of FP comparisons need an OR operation;
15410 under flag_finite_math_only we don't bother. */
15411 if (FLOAT_MODE_P (mode)
15412 && !flag_finite_math_only
15413 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15414 && (code == LE || code == GE
15415 || code == UNEQ || code == LTGT
15416 || code == UNGT || code == UNLT))
15418 enum rtx_code or1, or2;
15419 rtx or1_rtx, or2_rtx, compare2_rtx;
15420 rtx or_result = gen_reg_rtx (CCEQmode);
15424 case LE: or1 = LT; or2 = EQ; break;
15425 case GE: or1 = GT; or2 = EQ; break;
15426 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15427 case LTGT: or1 = LT; or2 = GT; break;
15428 case UNGT: or1 = UNORDERED; or2 = GT; break;
15429 case UNLT: or1 = UNORDERED; or2 = LT; break;
15430 default: gcc_unreachable ();
15432 validate_condition_mode (or1, comp_mode);
15433 validate_condition_mode (or2, comp_mode);
15434 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15435 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15436 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15437 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15439 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15441 compare_result = or_result;
15445 validate_condition_mode (code, GET_MODE (compare_result));
15447 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15451 /* Emit the RTL for an sCOND pattern. */
15454 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15457 enum machine_mode op_mode;
15458 enum rtx_code cond_code;
15459 rtx result = operands[0];
15461 condition_rtx = rs6000_generate_compare (operands[1], mode);
15462 cond_code = GET_CODE (condition_rtx);
15464 op_mode = GET_MODE (XEXP (operands[1], 0));
15465 if (op_mode == VOIDmode)
15466 op_mode = GET_MODE (XEXP (operands[1], 1));
15468 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15470 PUT_MODE (condition_rtx, DImode);
15471 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15472 || cond_code == LTU)
15473 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15474 force_reg (DImode, const1_rtx),
15475 force_reg (DImode, const0_rtx),
15476 XEXP (condition_rtx, 0)));
15478 emit_insn (gen_isel_signed_di (result, condition_rtx,
15479 force_reg (DImode, const1_rtx),
15480 force_reg (DImode, const0_rtx),
15481 XEXP (condition_rtx, 0)));
15485 PUT_MODE (condition_rtx, SImode);
15486 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15487 || cond_code == LTU)
15488 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15489 force_reg (SImode, const1_rtx),
15490 force_reg (SImode, const0_rtx),
15491 XEXP (condition_rtx, 0)));
15493 emit_insn (gen_isel_signed_si (result, condition_rtx,
15494 force_reg (SImode, const1_rtx),
15495 force_reg (SImode, const0_rtx),
15496 XEXP (condition_rtx, 0)));
15501 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15504 enum machine_mode op_mode;
15505 enum rtx_code cond_code;
15506 rtx result = operands[0];
15508 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15510 rs6000_emit_sISEL (mode, operands);
15514 condition_rtx = rs6000_generate_compare (operands[1], mode);
15515 cond_code = GET_CODE (condition_rtx);
15517 if (FLOAT_MODE_P (mode)
15518 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15522 PUT_MODE (condition_rtx, SImode);
15523 t = XEXP (condition_rtx, 0);
15525 gcc_assert (cond_code == NE || cond_code == EQ);
15527 if (cond_code == NE)
15528 emit_insn (gen_e500_flip_gt_bit (t, t));
15530 emit_insn (gen_move_from_CR_gt_bit (result, t));
15534 if (cond_code == NE
15535 || cond_code == GE || cond_code == LE
15536 || cond_code == GEU || cond_code == LEU
15537 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15539 rtx not_result = gen_reg_rtx (CCEQmode);
15540 rtx not_op, rev_cond_rtx;
15541 enum machine_mode cc_mode;
15543 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15545 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15546 SImode, XEXP (condition_rtx, 0), const0_rtx);
15547 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15548 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15549 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15552 op_mode = GET_MODE (XEXP (operands[1], 0));
15553 if (op_mode == VOIDmode)
15554 op_mode = GET_MODE (XEXP (operands[1], 1));
15556 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15558 PUT_MODE (condition_rtx, DImode);
15559 convert_move (result, condition_rtx, 0);
15563 PUT_MODE (condition_rtx, SImode);
15564 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15568 /* Emit a branch of kind CODE to location LOC. */
15571 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15573 rtx condition_rtx, loc_ref;
15575 condition_rtx = rs6000_generate_compare (operands[0], mode);
15576 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15577 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15578 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15579 loc_ref, pc_rtx)));
15582 /* Return the string to output a conditional branch to LABEL, which is
15583 the operand number of the label, or -1 if the branch is really a
15584 conditional return.
15586 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15587 condition code register and its mode specifies what kind of
15588 comparison we made.
15590 REVERSED is nonzero if we should reverse the sense of the comparison.
15592 INSN is the insn. */
15595 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15597 static char string[64];
15598 enum rtx_code code = GET_CODE (op);
15599 rtx cc_reg = XEXP (op, 0);
15600 enum machine_mode mode = GET_MODE (cc_reg);
15601 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15602 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15603 int really_reversed = reversed ^ need_longbranch;
15609 validate_condition_mode (code, mode);
15611 /* Work out which way this really branches. We could use
15612 reverse_condition_maybe_unordered here always but this
15613 makes the resulting assembler clearer. */
15614 if (really_reversed)
15616 /* Reversal of FP compares takes care -- an ordered compare
15617 becomes an unordered compare and vice versa. */
15618 if (mode == CCFPmode)
15619 code = reverse_condition_maybe_unordered (code);
15621 code = reverse_condition (code);
15624 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15626 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15631 /* Opposite of GT. */
15640 gcc_unreachable ();
15646 /* Not all of these are actually distinct opcodes, but
15647 we distinguish them for clarity of the resulting assembler. */
15648 case NE: case LTGT:
15649 ccode = "ne"; break;
15650 case EQ: case UNEQ:
15651 ccode = "eq"; break;
15653 ccode = "ge"; break;
15654 case GT: case GTU: case UNGT:
15655 ccode = "gt"; break;
15657 ccode = "le"; break;
15658 case LT: case LTU: case UNLT:
15659 ccode = "lt"; break;
15660 case UNORDERED: ccode = "un"; break;
15661 case ORDERED: ccode = "nu"; break;
15662 case UNGE: ccode = "nl"; break;
15663 case UNLE: ccode = "ng"; break;
15665 gcc_unreachable ();
15668 /* Maybe we have a guess as to how likely the branch is.
15669 The old mnemonics don't have a way to specify this information. */
15671 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15672 if (note != NULL_RTX)
15674 /* PROB is the difference from 50%. */
15675 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15677 /* Only hint for highly probable/improbable branches on newer
15678 cpus as static prediction overrides processor dynamic
15679 prediction. For older cpus we may as well always hint, but
15680 assume not taken for branches that are very close to 50% as a
15681 mispredicted taken branch is more expensive than a
15682 mispredicted not-taken branch. */
15683 if (rs6000_always_hint
15684 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15685 && br_prob_note_reliable_p (note)))
15687 if (abs (prob) > REG_BR_PROB_BASE / 20
15688 && ((prob > 0) ^ need_longbranch))
15696 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15698 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15700 /* We need to escape any '%' characters in the reg_names string.
15701 Assume they'd only be the first character.... */
15702 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15704 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15708 /* If the branch distance was too far, we may have to use an
15709 unconditional branch to go the distance. */
15710 if (need_longbranch)
15711 s += sprintf (s, ",$+8\n\tb %s", label);
15713 s += sprintf (s, ",%s", label);
15719 /* Return the string to flip the GT bit on a CR. */
15721 output_e500_flip_gt_bit (rtx dst, rtx src)
15723 static char string[64];
15726 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15727 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15730 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15731 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15733 sprintf (string, "crnot %d,%d", a, b);
15737 /* Return insn for VSX or Altivec comparisons. */
15740 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15743 enum machine_mode mode = GET_MODE (op0);
15751 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15757 mask = gen_reg_rtx (mode);
15758 emit_insn (gen_rtx_SET (VOIDmode,
15760 gen_rtx_fmt_ee (code, mode, op0, op1)));
15767 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15768 DMODE is expected destination mode. This is a recursive function. */
15771 rs6000_emit_vector_compare (enum rtx_code rcode,
15773 enum machine_mode dmode)
15776 bool swap_operands = false;
15777 bool try_again = false;
15779 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15780 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15782 /* See if the comparison works as is. */
15783 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15791 swap_operands = true;
15796 swap_operands = true;
15804 /* Invert condition and try again.
15805 e.g., A != B becomes ~(A==B). */
15807 enum rtx_code rev_code;
15808 enum insn_code nor_code;
15811 rev_code = reverse_condition_maybe_unordered (rcode);
15812 if (rev_code == UNKNOWN)
15815 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15816 if (nor_code == CODE_FOR_nothing)
15819 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15823 mask = gen_reg_rtx (dmode);
15824 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15832 /* Try GT/GTU/LT/LTU OR EQ */
15835 enum insn_code ior_code;
15836 enum rtx_code new_code;
15857 gcc_unreachable ();
15860 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15861 if (ior_code == CODE_FOR_nothing)
15864 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15868 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15872 mask = gen_reg_rtx (dmode);
15873 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15891 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15896 /* You only get two chances. */
15900 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15901 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15902 operands for the relation operation COND. */
15905 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15906 rtx cond, rtx cc_op0, rtx cc_op1)
15908 enum machine_mode dest_mode = GET_MODE (dest);
15909 enum rtx_code rcode = GET_CODE (cond);
15910 enum machine_mode cc_mode = CCmode;
15914 bool invert_move = false;
15916 if (VECTOR_UNIT_NONE_P (dest_mode))
15921 /* Swap operands if we can, and fall back to doing the operation as
15922 specified, and doing a NOR to invert the test. */
15928 /* Invert condition and try again.
15929 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15930 invert_move = true;
15931 rcode = reverse_condition_maybe_unordered (rcode);
15932 if (rcode == UNKNOWN)
15936 /* Mark unsigned tests with CCUNSmode. */
15941 cc_mode = CCUNSmode;
15948 /* Get the vector mask for the given relational operations. */
15949 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15957 op_true = op_false;
15961 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15962 emit_insn (gen_rtx_SET (VOIDmode,
15964 gen_rtx_IF_THEN_ELSE (dest_mode,
15971 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15972 operands of the last comparison is nonzero/true, FALSE_COND if it
15973 is zero/false. Return 0 if the hardware has no such operation. */
15976 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15978 enum rtx_code code = GET_CODE (op);
15979 rtx op0 = XEXP (op, 0);
15980 rtx op1 = XEXP (op, 1);
15981 REAL_VALUE_TYPE c1;
15982 enum machine_mode compare_mode = GET_MODE (op0);
15983 enum machine_mode result_mode = GET_MODE (dest);
15985 bool is_against_zero;
15987 /* These modes should always match. */
15988 if (GET_MODE (op1) != compare_mode
15989 /* In the isel case however, we can use a compare immediate, so
15990 op1 may be a small constant. */
15991 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15993 if (GET_MODE (true_cond) != result_mode)
15995 if (GET_MODE (false_cond) != result_mode)
15998 /* First, work out if the hardware can do this at all, or
15999 if it's too slow.... */
16000 if (!FLOAT_MODE_P (compare_mode))
16003 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16006 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16007 && SCALAR_FLOAT_MODE_P (compare_mode))
16010 is_against_zero = op1 == CONST0_RTX (compare_mode);
16012 /* A floating-point subtract might overflow, underflow, or produce
16013 an inexact result, thus changing the floating-point flags, so it
16014 can't be generated if we care about that. It's safe if one side
16015 of the construct is zero, since then no subtract will be
16017 if (SCALAR_FLOAT_MODE_P (compare_mode)
16018 && flag_trapping_math && ! is_against_zero)
16021 /* Eliminate half of the comparisons by switching operands, this
16022 makes the remaining code simpler. */
16023 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16024 || code == LTGT || code == LT || code == UNLE)
16026 code = reverse_condition_maybe_unordered (code);
16028 true_cond = false_cond;
16032 /* UNEQ and LTGT take four instructions for a comparison with zero,
16033 it'll probably be faster to use a branch here too. */
16034 if (code == UNEQ && HONOR_NANS (compare_mode))
16037 if (GET_CODE (op1) == CONST_DOUBLE)
16038 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16040 /* We're going to try to implement comparisons by performing
16041 a subtract, then comparing against zero. Unfortunately,
16042 Inf - Inf is NaN which is not zero, and so if we don't
16043 know that the operand is finite and the comparison
16044 would treat EQ different to UNORDERED, we can't do it. */
16045 if (HONOR_INFINITIES (compare_mode)
16046 && code != GT && code != UNGE
16047 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16048 /* Constructs of the form (a OP b ? a : b) are safe. */
16049 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16050 || (! rtx_equal_p (op0, true_cond)
16051 && ! rtx_equal_p (op1, true_cond))))
16054 /* At this point we know we can use fsel. */
16056 /* Reduce the comparison to a comparison against zero. */
16057 if (! is_against_zero)
16059 temp = gen_reg_rtx (compare_mode);
16060 emit_insn (gen_rtx_SET (VOIDmode, temp,
16061 gen_rtx_MINUS (compare_mode, op0, op1)));
16063 op1 = CONST0_RTX (compare_mode);
16066 /* If we don't care about NaNs we can reduce some of the comparisons
16067 down to faster ones. */
16068 if (! HONOR_NANS (compare_mode))
16074 true_cond = false_cond;
16087 /* Now, reduce everything down to a GE. */
16094 temp = gen_reg_rtx (compare_mode);
16095 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16100 temp = gen_reg_rtx (compare_mode);
16101 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16106 temp = gen_reg_rtx (compare_mode);
16107 emit_insn (gen_rtx_SET (VOIDmode, temp,
16108 gen_rtx_NEG (compare_mode,
16109 gen_rtx_ABS (compare_mode, op0))));
16114 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16115 temp = gen_reg_rtx (result_mode);
16116 emit_insn (gen_rtx_SET (VOIDmode, temp,
16117 gen_rtx_IF_THEN_ELSE (result_mode,
16118 gen_rtx_GE (VOIDmode,
16120 true_cond, false_cond)));
16121 false_cond = true_cond;
16124 temp = gen_reg_rtx (compare_mode);
16125 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16130 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16131 temp = gen_reg_rtx (result_mode);
16132 emit_insn (gen_rtx_SET (VOIDmode, temp,
16133 gen_rtx_IF_THEN_ELSE (result_mode,
16134 gen_rtx_GE (VOIDmode,
16136 true_cond, false_cond)));
16137 true_cond = false_cond;
16140 temp = gen_reg_rtx (compare_mode);
16141 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16146 gcc_unreachable ();
16149 emit_insn (gen_rtx_SET (VOIDmode, dest,
16150 gen_rtx_IF_THEN_ELSE (result_mode,
16151 gen_rtx_GE (VOIDmode,
16153 true_cond, false_cond)));
16157 /* Same as above, but for ints (isel). */
16160 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16162 rtx condition_rtx, cr;
16163 enum machine_mode mode = GET_MODE (dest);
16165 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16168 /* We still have to do the compare, because isel doesn't do a
16169 compare, it just looks at the CRx bits set by a previous compare
16171 condition_rtx = rs6000_generate_compare (op, mode);
16172 cr = XEXP (condition_rtx, 0);
16174 if (mode == SImode)
16176 if (GET_MODE (cr) == CCmode)
16177 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16178 true_cond, false_cond, cr));
16180 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16181 true_cond, false_cond, cr));
16185 if (GET_MODE (cr) == CCmode)
16186 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16187 true_cond, false_cond, cr));
16189 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16190 true_cond, false_cond, cr));
16197 output_isel (rtx *operands)
16199 enum rtx_code code;
16201 code = GET_CODE (operands[1]);
16202 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16204 PUT_CODE (operands[1], reverse_condition (code));
16205 return "isel %0,%3,%2,%j1";
16208 return "isel %0,%2,%3,%j1";
16212 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16214 enum machine_mode mode = GET_MODE (op0);
16218 /* VSX/altivec have direct min/max insns. */
16219 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16221 emit_insn (gen_rtx_SET (VOIDmode,
16223 gen_rtx_fmt_ee (code, mode, op0, op1)));
16227 if (code == SMAX || code == SMIN)
16232 if (code == SMAX || code == UMAX)
16233 target = emit_conditional_move (dest, c, op0, op1, mode,
16234 op0, op1, mode, 0);
16236 target = emit_conditional_move (dest, c, op0, op1, mode,
16237 op1, op0, mode, 0);
16238 gcc_assert (target);
16239 if (target != dest)
16240 emit_move_insn (dest, target);
16243 /* Emit instructions to perform a load-reserved/store-conditional operation.
16244 The operation performed is an atomic
16245 (set M (CODE:MODE M OP))
16246 If not NULL, BEFORE is atomically set to M before the operation, and
16247 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16248 If SYNC_P then a memory barrier is emitted before the operation.
16249 Either OP or M may be wrapped in a NOT operation. */
16252 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16253 rtx m, rtx op, rtx before_param, rtx after_param,
16256 enum machine_mode used_mode;
16257 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16260 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16261 rtx shift = NULL_RTX;
16264 emit_insn (gen_lwsync ());
16268 /* If this is smaller than SImode, we'll have to use SImode with
16270 if (mode == QImode || mode == HImode)
16274 if (MEM_ALIGN (used_m) >= 32)
16277 if (BYTES_BIG_ENDIAN)
16278 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16280 shift = GEN_INT (ishift);
16281 used_m = change_address (used_m, SImode, 0);
16285 rtx addrSI, aligned_addr;
16286 int shift_mask = mode == QImode ? 0x18 : 0x10;
16288 addrSI = gen_lowpart_common (SImode,
16289 force_reg (Pmode, XEXP (used_m, 0)));
16290 addrSI = force_reg (SImode, addrSI);
16291 shift = gen_reg_rtx (SImode);
16293 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16294 GEN_INT (shift_mask)));
16295 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16297 aligned_addr = expand_binop (Pmode, and_optab,
16299 GEN_INT (-4), NULL_RTX,
16300 1, OPTAB_LIB_WIDEN);
16301 used_m = change_address (used_m, SImode, aligned_addr);
16302 set_mem_align (used_m, 32);
16304 /* It's safe to keep the old alias set of USED_M, because
16305 the operation is atomic and only affects the original
16309 if (GET_CODE (op) == NOT)
16311 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16312 oldop = gen_rtx_NOT (SImode, oldop);
16315 oldop = lowpart_subreg (SImode, op, mode);
16321 newop = expand_binop (SImode, and_optab,
16322 oldop, GEN_INT (imask), NULL_RTX,
16323 1, OPTAB_LIB_WIDEN);
16324 emit_insn (gen_ashlsi3 (newop, newop, shift));
16327 case NOT: /* NAND */
16328 newop = expand_binop (SImode, ior_optab,
16329 oldop, GEN_INT (~imask), NULL_RTX,
16330 1, OPTAB_LIB_WIDEN);
16331 emit_insn (gen_rotlsi3 (newop, newop, shift));
16335 newop = expand_binop (SImode, ior_optab,
16336 oldop, GEN_INT (~imask), NULL_RTX,
16337 1, OPTAB_LIB_WIDEN);
16338 emit_insn (gen_rotlsi3 (newop, newop, shift));
16346 newop = expand_binop (SImode, and_optab,
16347 oldop, GEN_INT (imask), NULL_RTX,
16348 1, OPTAB_LIB_WIDEN);
16349 emit_insn (gen_ashlsi3 (newop, newop, shift));
16351 mask = gen_reg_rtx (SImode);
16352 emit_move_insn (mask, GEN_INT (imask));
16353 emit_insn (gen_ashlsi3 (mask, mask, shift));
16356 newop = gen_rtx_PLUS (SImode, m, newop);
16358 newop = gen_rtx_MINUS (SImode, m, newop);
16359 newop = gen_rtx_AND (SImode, newop, mask);
16360 newop = gen_rtx_IOR (SImode, newop,
16361 gen_rtx_AND (SImode,
16362 gen_rtx_NOT (SImode, mask),
16368 gcc_unreachable ();
16372 used_mode = SImode;
16373 before = gen_reg_rtx (used_mode);
16374 after = gen_reg_rtx (used_mode);
16379 before = before_param;
16380 after = after_param;
16382 if (before == NULL_RTX)
16383 before = gen_reg_rtx (used_mode);
16384 if (after == NULL_RTX)
16385 after = gen_reg_rtx (used_mode);
16388 if ((code == PLUS || code == MINUS)
16389 && used_mode != mode)
16390 the_op = op; /* Computed above. */
16391 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16392 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16393 else if (code == NOT)
16394 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16395 gen_rtx_NOT (used_mode, m),
16396 gen_rtx_NOT (used_mode, op));
16398 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16400 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16401 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16402 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16403 gen_rtx_UNSPEC (used_mode,
16404 gen_rtvec (1, the_op),
16406 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16408 if ((code == PLUS || code == MINUS) && used_mode != mode)
16409 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16410 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16412 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16413 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16415 /* Shift and mask the return values properly. */
16416 if (used_mode != mode && before_param)
16418 emit_insn (gen_lshrsi3 (before, before, shift));
16419 convert_move (before_param, before, 1);
16422 if (used_mode != mode && after_param)
16424 emit_insn (gen_lshrsi3 (after, after, shift));
16425 convert_move (after_param, after, 1);
16428 /* The previous sequence will end with a branch that's dependent on
16429 the conditional store, so placing an isync will ensure that no
16430 other instructions (especially, no load or store instructions)
16431 can start before the atomic operation completes. */
16433 emit_insn (gen_isync ());
16436 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16437 COND is true. Mark the jump as unlikely to be taken. */
16440 emit_unlikely_jump (rtx cond, rtx label)
16442 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16445 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16446 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16447 add_reg_note (x, REG_BR_PROB, very_unlikely);
16450 /* A subroutine of the atomic operation splitters. Emit a load-locked
16451 instruction in MODE. */
16454 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16456 rtx (*fn) (rtx, rtx) = NULL;
16457 if (mode == SImode)
16458 fn = gen_load_locked_si;
16459 else if (mode == DImode)
16460 fn = gen_load_locked_di;
16461 emit_insn (fn (reg, mem));
16464 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16465 instruction in MODE. */
16468 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16470 rtx (*fn) (rtx, rtx, rtx) = NULL;
16471 if (mode == SImode)
16472 fn = gen_store_conditional_si;
16473 else if (mode == DImode)
16474 fn = gen_store_conditional_di;
16476 /* Emit sync before stwcx. to address PPC405 Erratum. */
16477 if (PPC405_ERRATUM77)
16478 emit_insn (gen_memory_barrier ());
16480 emit_insn (fn (res, mem, val));
16483 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16484 to perform. MEM is the memory on which to operate. VAL is the second
16485 operand of the binary operator. BEFORE and AFTER are optional locations to
16486 return the value of MEM either before of after the operation. SCRATCH is
16487 a scratch register. */
16490 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16491 rtx before, rtx after, rtx scratch)
16493 enum machine_mode mode = GET_MODE (mem);
16494 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16496 emit_insn (gen_lwsync ());
16498 label = gen_label_rtx ();
16499 emit_label (label);
16500 label = gen_rtx_LABEL_REF (VOIDmode, label);
16502 if (before == NULL_RTX)
16504 emit_load_locked (mode, before, mem);
16507 x = gen_rtx_IOR (mode,
16508 gen_rtx_NOT (mode, before),
16509 gen_rtx_NOT (mode, val));
16510 else if (code == AND)
16511 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16513 x = gen_rtx_fmt_ee (code, mode, before, val);
16515 if (after != NULL_RTX)
16516 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16517 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16519 emit_store_conditional (mode, cond, mem, scratch);
16521 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16522 emit_unlikely_jump (x, label);
16524 emit_insn (gen_isync ());
16527 /* Expand an atomic compare and swap operation. MEM is the memory on which
16528 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16529 value to be stored. SCRATCH is a scratch GPR. */
16532 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16535 enum machine_mode mode = GET_MODE (mem);
16536 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16538 emit_insn (gen_lwsync ());
16540 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16541 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16542 emit_label (XEXP (label1, 0));
16544 emit_load_locked (mode, retval, mem);
16546 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16547 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16549 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16550 emit_unlikely_jump (x, label2);
16552 emit_move_insn (scratch, newval);
16553 emit_store_conditional (mode, cond, mem, scratch);
16555 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16556 emit_unlikely_jump (x, label1);
16558 emit_insn (gen_isync ());
16559 emit_label (XEXP (label2, 0));
16562 /* Expand an atomic test and set operation. MEM is the memory on which
16563 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16566 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16568 enum machine_mode mode = GET_MODE (mem);
16569 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16571 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16572 emit_label (XEXP (label, 0));
16574 emit_load_locked (mode, retval, mem);
16575 emit_move_insn (scratch, val);
16576 emit_store_conditional (mode, cond, mem, scratch);
16578 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16579 emit_unlikely_jump (x, label);
16581 emit_insn (gen_isync ());
16585 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16587 enum machine_mode mode = GET_MODE (mem);
16588 rtx addrSI, align, wdst, shift, mask;
16589 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16590 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16592 /* Shift amount for subword relative to aligned word. */
16593 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16594 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16595 shift = gen_reg_rtx (SImode);
16596 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16597 GEN_INT (shift_mask)));
16598 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16600 /* Shift and mask old value into position within word. */
16601 oldval = convert_modes (SImode, mode, oldval, 1);
16602 oldval = expand_binop (SImode, and_optab,
16603 oldval, GEN_INT (imask), NULL_RTX,
16604 1, OPTAB_LIB_WIDEN);
16605 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16607 /* Shift and mask new value into position within word. */
16608 newval = convert_modes (SImode, mode, newval, 1);
16609 newval = expand_binop (SImode, and_optab,
16610 newval, GEN_INT (imask), NULL_RTX,
16611 1, OPTAB_LIB_WIDEN);
16612 emit_insn (gen_ashlsi3 (newval, newval, shift));
16614 /* Mask for insertion. */
16615 mask = gen_reg_rtx (SImode);
16616 emit_move_insn (mask, GEN_INT (imask));
16617 emit_insn (gen_ashlsi3 (mask, mask, shift));
16619 /* Address of aligned word containing subword. */
16620 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16621 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16622 mem = change_address (mem, SImode, align);
16623 set_mem_align (mem, 32);
16624 MEM_VOLATILE_P (mem) = 1;
16626 wdst = gen_reg_rtx (SImode);
16627 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16628 oldval, newval, mem));
16630 /* Shift the result back. */
16631 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16633 emit_move_insn (dst, gen_lowpart (mode, wdst));
16637 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16638 rtx oldval, rtx newval, rtx mem,
16641 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16643 emit_insn (gen_lwsync ());
16644 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16645 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16646 emit_label (XEXP (label1, 0));
16648 emit_load_locked (SImode, scratch, mem);
16650 /* Mask subword within loaded value for comparison with oldval.
16651 Use UNSPEC_AND to avoid clobber.*/
16652 emit_insn (gen_rtx_SET (SImode, dest,
16653 gen_rtx_UNSPEC (SImode,
16654 gen_rtvec (2, scratch, mask),
16657 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16658 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16660 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16661 emit_unlikely_jump (x, label2);
16663 /* Clear subword within loaded value for insertion of new value. */
16664 emit_insn (gen_rtx_SET (SImode, scratch,
16665 gen_rtx_AND (SImode,
16666 gen_rtx_NOT (SImode, mask), scratch)));
16667 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16668 emit_store_conditional (SImode, cond, mem, scratch);
16670 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16671 emit_unlikely_jump (x, label1);
16673 emit_insn (gen_isync ());
16674 emit_label (XEXP (label2, 0));
16678 /* Emit instructions to move SRC to DST. Called by splitters for
16679 multi-register moves. It will emit at most one instruction for
16680 each register that is accessed; that is, it won't emit li/lis pairs
16681 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16685 rs6000_split_multireg_move (rtx dst, rtx src)
16687 /* The register number of the first register being moved. */
16689 /* The mode that is to be moved. */
16690 enum machine_mode mode;
16691 /* The mode that the move is being done in, and its size. */
16692 enum machine_mode reg_mode;
16694 /* The number of registers that will be moved. */
16697 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16698 mode = GET_MODE (dst);
16699 nregs = hard_regno_nregs[reg][mode];
16700 if (FP_REGNO_P (reg))
16701 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16702 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16703 else if (ALTIVEC_REGNO_P (reg))
16704 reg_mode = V16QImode;
16705 else if (TARGET_E500_DOUBLE && mode == TFmode)
16708 reg_mode = word_mode;
16709 reg_mode_size = GET_MODE_SIZE (reg_mode);
16711 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16713 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16715 /* Move register range backwards, if we might have destructive
16718 for (i = nregs - 1; i >= 0; i--)
16719 emit_insn (gen_rtx_SET (VOIDmode,
16720 simplify_gen_subreg (reg_mode, dst, mode,
16721 i * reg_mode_size),
16722 simplify_gen_subreg (reg_mode, src, mode,
16723 i * reg_mode_size)));
16729 bool used_update = false;
16730 rtx restore_basereg = NULL_RTX;
16732 if (MEM_P (src) && INT_REGNO_P (reg))
16736 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16737 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16740 breg = XEXP (XEXP (src, 0), 0);
16741 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16742 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16743 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16744 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16745 src = replace_equiv_address (src, breg);
16747 else if (! rs6000_offsettable_memref_p (src))
16749 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
16751 rtx basereg = XEXP (XEXP (src, 0), 0);
16754 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
16755 emit_insn (gen_rtx_SET (VOIDmode, ndst,
16756 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
16757 used_update = true;
16760 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16761 XEXP (XEXP (src, 0), 1)));
16762 src = replace_equiv_address (src, basereg);
16766 rtx basereg = gen_rtx_REG (Pmode, reg);
16767 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16768 src = replace_equiv_address (src, basereg);
16772 breg = XEXP (src, 0);
16773 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16774 breg = XEXP (breg, 0);
16776 /* If the base register we are using to address memory is
16777 also a destination reg, then change that register last. */
16779 && REGNO (breg) >= REGNO (dst)
16780 && REGNO (breg) < REGNO (dst) + nregs)
16781 j = REGNO (breg) - REGNO (dst);
16783 else if (MEM_P (dst) && INT_REGNO_P (reg))
16787 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16788 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16791 breg = XEXP (XEXP (dst, 0), 0);
16792 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16793 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16794 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16796 /* We have to update the breg before doing the store.
16797 Use store with update, if available. */
16801 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16802 emit_insn (TARGET_32BIT
16803 ? (TARGET_POWERPC64
16804 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16805 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16806 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16807 used_update = true;
16810 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16811 dst = replace_equiv_address (dst, breg);
16813 else if (!rs6000_offsettable_memref_p (dst)
16814 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
16816 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
16818 rtx basereg = XEXP (XEXP (dst, 0), 0);
16821 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16822 emit_insn (gen_rtx_SET (VOIDmode,
16823 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
16824 used_update = true;
16827 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16828 XEXP (XEXP (dst, 0), 1)));
16829 dst = replace_equiv_address (dst, basereg);
16833 rtx basereg = XEXP (XEXP (dst, 0), 0);
16834 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
16835 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
16837 && REG_P (offsetreg)
16838 && REGNO (basereg) != REGNO (offsetreg));
16839 if (REGNO (basereg) == 0)
16841 rtx tmp = offsetreg;
16842 offsetreg = basereg;
16845 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
16846 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
16847 dst = replace_equiv_address (dst, basereg);
16850 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
16851 gcc_assert (rs6000_offsettable_memref_p (dst));
16854 for (i = 0; i < nregs; i++)
16856 /* Calculate index to next subword. */
16861 /* If compiler already emitted move of first word by
16862 store with update, no need to do anything. */
16863 if (j == 0 && used_update)
16866 emit_insn (gen_rtx_SET (VOIDmode,
16867 simplify_gen_subreg (reg_mode, dst, mode,
16868 j * reg_mode_size),
16869 simplify_gen_subreg (reg_mode, src, mode,
16870 j * reg_mode_size)));
16872 if (restore_basereg != NULL_RTX)
16873 emit_insn (restore_basereg);
16878 /* This page contains routines that are used to determine what the
16879 function prologue and epilogue code will do and write them out. */
16881 /* Return the first fixed-point register that is required to be
16882 saved. 32 if none. */
16885 first_reg_to_save (void)
16889 /* Find lowest numbered live register. */
16890 for (first_reg = 13; first_reg <= 31; first_reg++)
16891 if (df_regs_ever_live_p (first_reg)
16892 && (! call_used_regs[first_reg]
16893 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16894 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16895 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16896 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16901 && crtl->uses_pic_offset_table
16902 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16903 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16909 /* Similar, for FP regs. */
16912 first_fp_reg_to_save (void)
16916 /* Find lowest numbered live register. */
16917 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16918 if (df_regs_ever_live_p (first_reg))
16924 /* Similar, for AltiVec regs. */
16927 first_altivec_reg_to_save (void)
16931 /* Stack frame remains as is unless we are in AltiVec ABI. */
16932 if (! TARGET_ALTIVEC_ABI)
16933 return LAST_ALTIVEC_REGNO + 1;
16935 /* On Darwin, the unwind routines are compiled without
16936 TARGET_ALTIVEC, and use save_world to save/restore the
16937 altivec registers when necessary. */
16938 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16939 && ! TARGET_ALTIVEC)
16940 return FIRST_ALTIVEC_REGNO + 20;
16942 /* Find lowest numbered live register. */
16943 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16944 if (df_regs_ever_live_p (i))
16950 /* Return a 32-bit mask of the AltiVec registers we need to set in
16951 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16952 the 32-bit word is 0. */
16954 static unsigned int
16955 compute_vrsave_mask (void)
16957 unsigned int i, mask = 0;
16959 /* On Darwin, the unwind routines are compiled without
16960 TARGET_ALTIVEC, and use save_world to save/restore the
16961 call-saved altivec registers when necessary. */
16962 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16963 && ! TARGET_ALTIVEC)
16966 /* First, find out if we use _any_ altivec registers. */
16967 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16968 if (df_regs_ever_live_p (i))
16969 mask |= ALTIVEC_REG_BIT (i);
16974 /* Next, remove the argument registers from the set. These must
16975 be in the VRSAVE mask set by the caller, so we don't need to add
16976 them in again. More importantly, the mask we compute here is
16977 used to generate CLOBBERs in the set_vrsave insn, and we do not
16978 wish the argument registers to die. */
16979 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16980 mask &= ~ALTIVEC_REG_BIT (i);
16982 /* Similarly, remove the return value from the set. */
16985 diddle_return_value (is_altivec_return_reg, &yes);
16987 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16993 /* For a very restricted set of circumstances, we can cut down the
16994 size of prologues/epilogues by calling our own save/restore-the-world
16998 compute_save_world_info (rs6000_stack_t *info_ptr)
17000 info_ptr->world_save_p = 1;
17001 info_ptr->world_save_p
17002 = (WORLD_SAVE_P (info_ptr)
17003 && DEFAULT_ABI == ABI_DARWIN
17004 && ! (cfun->calls_setjmp && flag_exceptions)
17005 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17006 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17007 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17008 && info_ptr->cr_save_p);
17010 /* This will not work in conjunction with sibcalls. Make sure there
17011 are none. (This check is expensive, but seldom executed.) */
17012 if (WORLD_SAVE_P (info_ptr))
17015 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17016 if ( GET_CODE (insn) == CALL_INSN
17017 && SIBLING_CALL_P (insn))
17019 info_ptr->world_save_p = 0;
17024 if (WORLD_SAVE_P (info_ptr))
17026 /* Even if we're not touching VRsave, make sure there's room on the
17027 stack for it, if it looks like we're calling SAVE_WORLD, which
17028 will attempt to save it. */
17029 info_ptr->vrsave_size = 4;
17031 /* If we are going to save the world, we need to save the link register too. */
17032 info_ptr->lr_save_p = 1;
17034 /* "Save" the VRsave register too if we're saving the world. */
17035 if (info_ptr->vrsave_mask == 0)
17036 info_ptr->vrsave_mask = compute_vrsave_mask ();
17038 /* Because the Darwin register save/restore routines only handle
17039 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17041 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17042 && (info_ptr->first_altivec_reg_save
17043 >= FIRST_SAVED_ALTIVEC_REGNO));
17050 is_altivec_return_reg (rtx reg, void *xyes)
17052 bool *yes = (bool *) xyes;
17053 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17058 /* Calculate the stack information for the current function. This is
17059 complicated by having two separate calling sequences, the AIX calling
17060 sequence and the V.4 calling sequence.
17062 AIX (and Darwin/Mac OS X) stack frames look like:
17064 SP----> +---------------------------------------+
17065 | back chain to caller | 0 0
17066 +---------------------------------------+
17067 | saved CR | 4 8 (8-11)
17068 +---------------------------------------+
17070 +---------------------------------------+
17071 | reserved for compilers | 12 24
17072 +---------------------------------------+
17073 | reserved for binders | 16 32
17074 +---------------------------------------+
17075 | saved TOC pointer | 20 40
17076 +---------------------------------------+
17077 | Parameter save area (P) | 24 48
17078 +---------------------------------------+
17079 | Alloca space (A) | 24+P etc.
17080 +---------------------------------------+
17081 | Local variable space (L) | 24+P+A
17082 +---------------------------------------+
17083 | Float/int conversion temporary (X) | 24+P+A+L
17084 +---------------------------------------+
17085 | Save area for AltiVec registers (W) | 24+P+A+L+X
17086 +---------------------------------------+
17087 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17088 +---------------------------------------+
17089 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17090 +---------------------------------------+
17091 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17092 +---------------------------------------+
17093 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17094 +---------------------------------------+
17095 old SP->| back chain to caller's caller |
17096 +---------------------------------------+
17098 The required alignment for AIX configurations is two words (i.e., 8
17102 V.4 stack frames look like:
17104 SP----> +---------------------------------------+
17105 | back chain to caller | 0
17106 +---------------------------------------+
17107 | caller's saved LR | 4
17108 +---------------------------------------+
17109 | Parameter save area (P) | 8
17110 +---------------------------------------+
17111 | Alloca space (A) | 8+P
17112 +---------------------------------------+
17113 | Varargs save area (V) | 8+P+A
17114 +---------------------------------------+
17115 | Local variable space (L) | 8+P+A+V
17116 +---------------------------------------+
17117 | Float/int conversion temporary (X) | 8+P+A+V+L
17118 +---------------------------------------+
17119 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17120 +---------------------------------------+
17121 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17122 +---------------------------------------+
17123 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17124 +---------------------------------------+
17125 | SPE: area for 64-bit GP registers |
17126 +---------------------------------------+
17127 | SPE alignment padding |
17128 +---------------------------------------+
17129 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17130 +---------------------------------------+
17131 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17132 +---------------------------------------+
17133 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17134 +---------------------------------------+
17135 old SP->| back chain to caller's caller |
17136 +---------------------------------------+
17138 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17139 given. (But note below and in sysv4.h that we require only 8 and
17140 may round up the size of our stack frame anyways. The historical
17141 reason is early versions of powerpc-linux which didn't properly
17142 align the stack at program startup. A happy side-effect is that
17143 -mno-eabi libraries can be used with -meabi programs.)
17145 The EABI configuration defaults to the V.4 layout. However,
17146 the stack alignment requirements may differ. If -mno-eabi is not
17147 given, the required stack alignment is 8 bytes; if -mno-eabi is
17148 given, the required alignment is 16 bytes. (But see V.4 comment
17151 #ifndef ABI_STACK_BOUNDARY
17152 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17155 static rs6000_stack_t *
17156 rs6000_stack_info (void)
17158 static rs6000_stack_t info;
17159 rs6000_stack_t *info_ptr = &info;
17160 int reg_size = TARGET_32BIT ? 4 : 8;
17164 HOST_WIDE_INT non_fixed_size;
17166 memset (&info, 0, sizeof (info));
17170 /* Cache value so we don't rescan instruction chain over and over. */
17171 if (cfun->machine->insn_chain_scanned_p == 0)
17172 cfun->machine->insn_chain_scanned_p
17173 = spe_func_has_64bit_regs_p () + 1;
17174 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17177 /* Select which calling sequence. */
17178 info_ptr->abi = DEFAULT_ABI;
17180 /* Calculate which registers need to be saved & save area size. */
17181 info_ptr->first_gp_reg_save = first_reg_to_save ();
17182 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17183 even if it currently looks like we won't. Reload may need it to
17184 get at a constant; if so, it will have already created a constant
17185 pool entry for it. */
17186 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17187 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17188 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17189 && crtl->uses_const_pool
17190 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17191 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17193 first_gp = info_ptr->first_gp_reg_save;
17195 info_ptr->gp_size = reg_size * (32 - first_gp);
17197 /* For the SPE, we have an additional upper 32-bits on each GPR.
17198 Ideally we should save the entire 64-bits only when the upper
17199 half is used in SIMD instructions. Since we only record
17200 registers live (not the size they are used in), this proves
17201 difficult because we'd have to traverse the instruction chain at
17202 the right time, taking reload into account. This is a real pain,
17203 so we opt to save the GPRs in 64-bits always if but one register
17204 gets used in 64-bits. Otherwise, all the registers in the frame
17205 get saved in 32-bits.
17207 So... since when we save all GPRs (except the SP) in 64-bits, the
17208 traditional GP save area will be empty. */
17209 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17210 info_ptr->gp_size = 0;
17212 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17213 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17215 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17216 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17217 - info_ptr->first_altivec_reg_save);
17219 /* Does this function call anything? */
17220 info_ptr->calls_p = (! current_function_is_leaf
17221 || cfun->machine->ra_needs_full_frame);
17223 /* Determine if we need to save the link register. */
17224 if ((DEFAULT_ABI == ABI_AIX
17226 && !TARGET_PROFILE_KERNEL)
17227 #ifdef TARGET_RELOCATABLE
17228 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17230 || (info_ptr->first_fp_reg_save != 64
17231 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17232 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17233 || info_ptr->calls_p
17234 || rs6000_ra_ever_killed ())
17236 info_ptr->lr_save_p = 1;
17237 df_set_regs_ever_live (LR_REGNO, true);
17240 /* Determine if we need to save the condition code registers. */
17241 if (df_regs_ever_live_p (CR2_REGNO)
17242 || df_regs_ever_live_p (CR3_REGNO)
17243 || df_regs_ever_live_p (CR4_REGNO))
17245 info_ptr->cr_save_p = 1;
17246 if (DEFAULT_ABI == ABI_V4)
17247 info_ptr->cr_size = reg_size;
17250 /* If the current function calls __builtin_eh_return, then we need
17251 to allocate stack space for registers that will hold data for
17252 the exception handler. */
17253 if (crtl->calls_eh_return)
17256 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17259 /* SPE saves EH registers in 64-bits. */
17260 ehrd_size = i * (TARGET_SPE_ABI
17261 && info_ptr->spe_64bit_regs_used != 0
17262 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17267 /* Determine various sizes. */
17268 info_ptr->reg_size = reg_size;
17269 info_ptr->fixed_size = RS6000_SAVE_AREA;
17270 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17271 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17272 TARGET_ALTIVEC ? 16 : 8);
17273 if (FRAME_GROWS_DOWNWARD)
17274 info_ptr->vars_size
17275 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17276 + info_ptr->parm_size,
17277 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17278 - (info_ptr->fixed_size + info_ptr->vars_size
17279 + info_ptr->parm_size);
17281 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17282 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17284 info_ptr->spe_gp_size = 0;
17286 if (TARGET_ALTIVEC_ABI)
17287 info_ptr->vrsave_mask = compute_vrsave_mask ();
17289 info_ptr->vrsave_mask = 0;
17291 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17292 info_ptr->vrsave_size = 4;
17294 info_ptr->vrsave_size = 0;
17296 compute_save_world_info (info_ptr);
17298 /* Calculate the offsets. */
17299 switch (DEFAULT_ABI)
17303 gcc_unreachable ();
17307 info_ptr->fp_save_offset = - info_ptr->fp_size;
17308 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17310 if (TARGET_ALTIVEC_ABI)
17312 info_ptr->vrsave_save_offset
17313 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17315 /* Align stack so vector save area is on a quadword boundary.
17316 The padding goes above the vectors. */
17317 if (info_ptr->altivec_size != 0)
17318 info_ptr->altivec_padding_size
17319 = info_ptr->vrsave_save_offset & 0xF;
17321 info_ptr->altivec_padding_size = 0;
17323 info_ptr->altivec_save_offset
17324 = info_ptr->vrsave_save_offset
17325 - info_ptr->altivec_padding_size
17326 - info_ptr->altivec_size;
17327 gcc_assert (info_ptr->altivec_size == 0
17328 || info_ptr->altivec_save_offset % 16 == 0);
17330 /* Adjust for AltiVec case. */
17331 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17334 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17335 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17336 info_ptr->lr_save_offset = 2*reg_size;
17340 info_ptr->fp_save_offset = - info_ptr->fp_size;
17341 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17342 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17344 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17346 /* Align stack so SPE GPR save area is aligned on a
17347 double-word boundary. */
17348 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17349 info_ptr->spe_padding_size
17350 = 8 - (-info_ptr->cr_save_offset % 8);
17352 info_ptr->spe_padding_size = 0;
17354 info_ptr->spe_gp_save_offset
17355 = info_ptr->cr_save_offset
17356 - info_ptr->spe_padding_size
17357 - info_ptr->spe_gp_size;
17359 /* Adjust for SPE case. */
17360 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17362 else if (TARGET_ALTIVEC_ABI)
17364 info_ptr->vrsave_save_offset
17365 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17367 /* Align stack so vector save area is on a quadword boundary. */
17368 if (info_ptr->altivec_size != 0)
17369 info_ptr->altivec_padding_size
17370 = 16 - (-info_ptr->vrsave_save_offset % 16);
17372 info_ptr->altivec_padding_size = 0;
17374 info_ptr->altivec_save_offset
17375 = info_ptr->vrsave_save_offset
17376 - info_ptr->altivec_padding_size
17377 - info_ptr->altivec_size;
17379 /* Adjust for AltiVec case. */
17380 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17383 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17384 info_ptr->ehrd_offset -= ehrd_size;
17385 info_ptr->lr_save_offset = reg_size;
17389 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17390 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17391 + info_ptr->gp_size
17392 + info_ptr->altivec_size
17393 + info_ptr->altivec_padding_size
17394 + info_ptr->spe_gp_size
17395 + info_ptr->spe_padding_size
17397 + info_ptr->cr_size
17398 + info_ptr->vrsave_size,
17401 non_fixed_size = (info_ptr->vars_size
17402 + info_ptr->parm_size
17403 + info_ptr->save_size);
17405 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17406 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17408 /* Determine if we need to allocate any stack frame:
17410 For AIX we need to push the stack if a frame pointer is needed
17411 (because the stack might be dynamically adjusted), if we are
17412 debugging, if we make calls, or if the sum of fp_save, gp_save,
17413 and local variables are more than the space needed to save all
17414 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17415 + 18*8 = 288 (GPR13 reserved).
17417 For V.4 we don't have the stack cushion that AIX uses, but assume
17418 that the debugger can handle stackless frames. */
17420 if (info_ptr->calls_p)
17421 info_ptr->push_p = 1;
17423 else if (DEFAULT_ABI == ABI_V4)
17424 info_ptr->push_p = non_fixed_size != 0;
17426 else if (frame_pointer_needed)
17427 info_ptr->push_p = 1;
17429 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17430 info_ptr->push_p = 1;
17433 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17435 /* Zero offsets if we're not saving those registers. */
17436 if (info_ptr->fp_size == 0)
17437 info_ptr->fp_save_offset = 0;
17439 if (info_ptr->gp_size == 0)
17440 info_ptr->gp_save_offset = 0;
17442 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17443 info_ptr->altivec_save_offset = 0;
17445 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17446 info_ptr->vrsave_save_offset = 0;
17448 if (! TARGET_SPE_ABI
17449 || info_ptr->spe_64bit_regs_used == 0
17450 || info_ptr->spe_gp_size == 0)
17451 info_ptr->spe_gp_save_offset = 0;
17453 if (! info_ptr->lr_save_p)
17454 info_ptr->lr_save_offset = 0;
17456 if (! info_ptr->cr_save_p)
17457 info_ptr->cr_save_offset = 0;
17462 /* Return true if the current function uses any GPRs in 64-bit SIMD
17466 spe_func_has_64bit_regs_p (void)
17470 /* Functions that save and restore all the call-saved registers will
17471 need to save/restore the registers in 64-bits. */
17472 if (crtl->calls_eh_return
17473 || cfun->calls_setjmp
17474 || crtl->has_nonlocal_goto)
17477 insns = get_insns ();
17479 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17485 /* FIXME: This should be implemented with attributes...
17487 (set_attr "spe64" "true")....then,
17488 if (get_spe64(insn)) return true;
17490 It's the only reliable way to do the stuff below. */
17492 i = PATTERN (insn);
17493 if (GET_CODE (i) == SET)
17495 enum machine_mode mode = GET_MODE (SET_SRC (i));
17497 if (SPE_VECTOR_MODE (mode))
17499 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17509 debug_stack_info (rs6000_stack_t *info)
17511 const char *abi_string;
17514 info = rs6000_stack_info ();
17516 fprintf (stderr, "\nStack information for function %s:\n",
17517 ((current_function_decl && DECL_NAME (current_function_decl))
17518 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17523 default: abi_string = "Unknown"; break;
17524 case ABI_NONE: abi_string = "NONE"; break;
17525 case ABI_AIX: abi_string = "AIX"; break;
17526 case ABI_DARWIN: abi_string = "Darwin"; break;
17527 case ABI_V4: abi_string = "V.4"; break;
17530 fprintf (stderr, "\tABI = %5s\n", abi_string);
17532 if (TARGET_ALTIVEC_ABI)
17533 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17535 if (TARGET_SPE_ABI)
17536 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17538 if (info->first_gp_reg_save != 32)
17539 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17541 if (info->first_fp_reg_save != 64)
17542 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17544 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17545 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17546 info->first_altivec_reg_save);
17548 if (info->lr_save_p)
17549 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17551 if (info->cr_save_p)
17552 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17554 if (info->vrsave_mask)
17555 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17558 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17561 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17563 if (info->gp_save_offset)
17564 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17566 if (info->fp_save_offset)
17567 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17569 if (info->altivec_save_offset)
17570 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17571 info->altivec_save_offset);
17573 if (info->spe_gp_save_offset)
17574 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17575 info->spe_gp_save_offset);
17577 if (info->vrsave_save_offset)
17578 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17579 info->vrsave_save_offset);
17581 if (info->lr_save_offset)
17582 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17584 if (info->cr_save_offset)
17585 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17587 if (info->varargs_save_offset)
17588 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17590 if (info->total_size)
17591 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17594 if (info->vars_size)
17595 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17598 if (info->parm_size)
17599 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17601 if (info->fixed_size)
17602 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17605 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17607 if (info->spe_gp_size)
17608 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17611 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17613 if (info->altivec_size)
17614 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17616 if (info->vrsave_size)
17617 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17619 if (info->altivec_padding_size)
17620 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17621 info->altivec_padding_size);
17623 if (info->spe_padding_size)
17624 fprintf (stderr, "\tspe_padding_size = %5d\n",
17625 info->spe_padding_size);
17628 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17630 if (info->save_size)
17631 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17633 if (info->reg_size != 4)
17634 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17636 fprintf (stderr, "\n");
17640 rs6000_return_addr (int count, rtx frame)
17642 /* Currently we don't optimize very well between prolog and body
17643 code and for PIC code the code can be actually quite bad, so
17644 don't try to be too clever here. */
17645 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17647 cfun->machine->ra_needs_full_frame = 1;
17654 plus_constant (copy_to_reg
17655 (gen_rtx_MEM (Pmode,
17656 memory_address (Pmode, frame))),
17657 RETURN_ADDRESS_OFFSET)));
17660 cfun->machine->ra_need_lr = 1;
17661 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17664 /* Say whether a function is a candidate for sibcall handling or not.
17665 We do not allow indirect calls to be optimized into sibling calls.
17666 Also, we can't do it if there are any vector parameters; there's
17667 nowhere to put the VRsave code so it works; note that functions with
17668 vector parameters are required to have a prototype, so the argument
17669 type info must be available here. (The tail recursion case can work
17670 with vector parameters, but there's no way to distinguish here.) */
17672 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17677 if (TARGET_ALTIVEC_VRSAVE)
17679 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17680 type; type = TREE_CHAIN (type))
17682 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17686 if (DEFAULT_ABI == ABI_DARWIN
17687 || ((*targetm.binds_local_p) (decl)
17688 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17690 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17692 if (!lookup_attribute ("longcall", attr_list)
17693 || lookup_attribute ("shortcall", attr_list))
17700 /* NULL if INSN insn is valid within a low-overhead loop.
17701 Otherwise return why doloop cannot be applied.
17702 PowerPC uses the COUNT register for branch on table instructions. */
17704 static const char *
17705 rs6000_invalid_within_doloop (const_rtx insn)
17708 return "Function call in the loop.";
17711 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17712 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17713 return "Computed branch in the loop.";
17719 rs6000_ra_ever_killed (void)
17725 if (cfun->is_thunk)
17728 /* regs_ever_live has LR marked as used if any sibcalls are present,
17729 but this should not force saving and restoring in the
17730 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17731 clobbers LR, so that is inappropriate. */
17733 /* Also, the prologue can generate a store into LR that
17734 doesn't really count, like this:
17737 bcl to set PIC register
17741 When we're called from the epilogue, we need to avoid counting
17742 this as a store. */
17744 push_topmost_sequence ();
17745 top = get_insns ();
17746 pop_topmost_sequence ();
17747 reg = gen_rtx_REG (Pmode, LR_REGNO);
17749 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17755 if (!SIBLING_CALL_P (insn))
17758 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17760 else if (set_of (reg, insn) != NULL_RTX
17761 && !prologue_epilogue_contains (insn))
17768 /* Emit instructions needed to load the TOC register.
17769 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17770 a constant pool; or for SVR4 -fpic. */
17773 rs6000_emit_load_toc_table (int fromprolog)
17776 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17778 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17781 rtx lab, tmp1, tmp2, got;
17783 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17784 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17786 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17788 got = rs6000_got_sym ();
17789 tmp1 = tmp2 = dest;
17792 tmp1 = gen_reg_rtx (Pmode);
17793 tmp2 = gen_reg_rtx (Pmode);
17795 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17796 emit_move_insn (tmp1,
17797 gen_rtx_REG (Pmode, LR_REGNO));
17798 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17799 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17801 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17803 emit_insn (gen_load_toc_v4_pic_si ());
17804 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17806 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17809 rtx temp0 = (fromprolog
17810 ? gen_rtx_REG (Pmode, 0)
17811 : gen_reg_rtx (Pmode));
17817 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17818 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17820 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17821 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17823 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17824 emit_move_insn (dest,
17825 gen_rtx_REG (Pmode, LR_REGNO));
17826 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17832 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17833 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17834 emit_move_insn (dest,
17835 gen_rtx_REG (Pmode, LR_REGNO));
17836 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17838 emit_insn (gen_addsi3 (dest, temp0, dest));
17840 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17842 /* This is for AIX code running in non-PIC ELF32. */
17845 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17846 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17848 emit_insn (gen_elf_high (dest, realsym));
17849 emit_insn (gen_elf_low (dest, dest, realsym));
17853 gcc_assert (DEFAULT_ABI == ABI_AIX);
17856 emit_insn (gen_load_toc_aix_si (dest));
17858 emit_insn (gen_load_toc_aix_di (dest));
17862 /* Emit instructions to restore the link register after determining where
17863 its value has been stored. */
17866 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17868 rs6000_stack_t *info = rs6000_stack_info ();
17871 operands[0] = source;
17872 operands[1] = scratch;
17874 if (info->lr_save_p)
17876 rtx frame_rtx = stack_pointer_rtx;
17877 HOST_WIDE_INT sp_offset = 0;
17880 if (frame_pointer_needed
17881 || cfun->calls_alloca
17882 || info->total_size > 32767)
17884 tmp = gen_frame_mem (Pmode, frame_rtx);
17885 emit_move_insn (operands[1], tmp);
17886 frame_rtx = operands[1];
17888 else if (info->push_p)
17889 sp_offset = info->total_size;
17891 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17892 tmp = gen_frame_mem (Pmode, tmp);
17893 emit_move_insn (tmp, operands[0]);
17896 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17899 static GTY(()) alias_set_type set = -1;
17902 get_TOC_alias_set (void)
17905 set = new_alias_set ();
17909 /* This returns nonzero if the current function uses the TOC. This is
17910 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17911 is generated by the ABI_V4 load_toc_* patterns. */
17918 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17921 rtx pat = PATTERN (insn);
17924 if (GET_CODE (pat) == PARALLEL)
17925 for (i = 0; i < XVECLEN (pat, 0); i++)
17927 rtx sub = XVECEXP (pat, 0, i);
17928 if (GET_CODE (sub) == USE)
17930 sub = XEXP (sub, 0);
17931 if (GET_CODE (sub) == UNSPEC
17932 && XINT (sub, 1) == UNSPEC_TOC)
17942 create_TOC_reference (rtx symbol)
17944 if (TARGET_DEBUG_ADDR)
17946 if (GET_CODE (symbol) == SYMBOL_REF)
17947 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17951 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17952 GET_RTX_NAME (GET_CODE (symbol)));
17953 debug_rtx (symbol);
17957 if (!can_create_pseudo_p ())
17958 df_set_regs_ever_live (TOC_REGISTER, true);
17959 return gen_rtx_PLUS (Pmode,
17960 gen_rtx_REG (Pmode, TOC_REGISTER),
17961 gen_rtx_CONST (Pmode,
17962 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17965 /* Issue assembly directives that create a reference to the given DWARF
17966 FRAME_TABLE_LABEL from the current function section. */
17968 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17970 fprintf (asm_out_file, "\t.ref %s\n",
17971 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17974 /* If _Unwind_* has been called from within the same module,
17975 toc register is not guaranteed to be saved to 40(1) on function
17976 entry. Save it there in that case. */
17979 rs6000_aix_emit_builtin_unwind_init (void)
17982 rtx stack_top = gen_reg_rtx (Pmode);
17983 rtx opcode_addr = gen_reg_rtx (Pmode);
17984 rtx opcode = gen_reg_rtx (SImode);
17985 rtx tocompare = gen_reg_rtx (SImode);
17986 rtx no_toc_save_needed = gen_label_rtx ();
17988 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17989 emit_move_insn (stack_top, mem);
17991 mem = gen_frame_mem (Pmode,
17992 gen_rtx_PLUS (Pmode, stack_top,
17993 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17994 emit_move_insn (opcode_addr, mem);
17995 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17996 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17997 : 0xE8410028, SImode));
17999 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18000 SImode, NULL_RTX, NULL_RTX,
18001 no_toc_save_needed, -1);
18003 mem = gen_frame_mem (Pmode,
18004 gen_rtx_PLUS (Pmode, stack_top,
18005 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18006 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18007 emit_label (no_toc_save_needed);
18010 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18011 and the change to the stack pointer. */
18014 rs6000_emit_stack_tie (void)
18016 rtx mem = gen_frame_mem (BLKmode,
18017 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18019 emit_insn (gen_stack_tie (mem));
18022 /* Emit the correct code for allocating stack space, as insns.
18023 If COPY_R12, make sure a copy of the old frame is left in r12.
18024 If COPY_R11, make sure a copy of the old frame is left in r11,
18025 in preference to r12 if COPY_R12.
18026 The generated code may use hard register 0 as a temporary. */
18029 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
18032 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18033 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18034 rtx todec = gen_int_mode (-size, Pmode);
18037 if (INTVAL (todec) != -size)
18039 warning (0, "stack frame too large");
18040 emit_insn (gen_trap ());
18044 if (crtl->limit_stack)
18046 if (REG_P (stack_limit_rtx)
18047 && REGNO (stack_limit_rtx) > 1
18048 && REGNO (stack_limit_rtx) <= 31)
18050 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18051 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18054 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18056 && DEFAULT_ABI == ABI_V4)
18058 rtx toload = gen_rtx_CONST (VOIDmode,
18059 gen_rtx_PLUS (Pmode,
18063 emit_insn (gen_elf_high (tmp_reg, toload));
18064 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18065 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18069 warning (0, "stack limit expression is not supported");
18072 if (copy_r12 || copy_r11)
18073 emit_move_insn (copy_r11
18074 ? gen_rtx_REG (Pmode, 11)
18075 : gen_rtx_REG (Pmode, 12),
18080 /* Need a note here so that try_split doesn't get confused. */
18081 if (get_last_insn () == NULL_RTX)
18082 emit_note (NOTE_INSN_DELETED);
18083 insn = emit_move_insn (tmp_reg, todec);
18084 try_split (PATTERN (insn), insn, 0);
18088 insn = emit_insn (TARGET_32BIT
18089 ? gen_movsi_update_stack (stack_reg, stack_reg,
18091 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18092 todec, stack_reg));
18093 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18094 it now and set the alias set/attributes. The above gen_*_update
18095 calls will generate a PARALLEL with the MEM set being the first
18097 par = PATTERN (insn);
18098 gcc_assert (GET_CODE (par) == PARALLEL);
18099 set = XVECEXP (par, 0, 0);
18100 gcc_assert (GET_CODE (set) == SET);
18101 mem = SET_DEST (set);
18102 gcc_assert (MEM_P (mem));
18103 MEM_NOTRAP_P (mem) = 1;
18104 set_mem_alias_set (mem, get_frame_alias_set ());
18106 RTX_FRAME_RELATED_P (insn) = 1;
18107 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18108 gen_rtx_SET (VOIDmode, stack_reg,
18109 gen_rtx_PLUS (Pmode, stack_reg,
18110 GEN_INT (-size))));
18113 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18114 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18115 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18116 deduce these equivalences by itself so it wasn't necessary to hold
18117 its hand so much. */
18120 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18121 rtx reg2, rtx rreg)
18125 /* copy_rtx will not make unique copies of registers, so we need to
18126 ensure we don't have unwanted sharing here. */
18128 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18131 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18133 real = copy_rtx (PATTERN (insn));
18135 if (reg2 != NULL_RTX)
18136 real = replace_rtx (real, reg2, rreg);
18138 real = replace_rtx (real, reg,
18139 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18140 STACK_POINTER_REGNUM),
18143 /* We expect that 'real' is either a SET or a PARALLEL containing
18144 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18145 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18147 if (GET_CODE (real) == SET)
18151 temp = simplify_rtx (SET_SRC (set));
18153 SET_SRC (set) = temp;
18154 temp = simplify_rtx (SET_DEST (set));
18156 SET_DEST (set) = temp;
18157 if (GET_CODE (SET_DEST (set)) == MEM)
18159 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18161 XEXP (SET_DEST (set), 0) = temp;
18168 gcc_assert (GET_CODE (real) == PARALLEL);
18169 for (i = 0; i < XVECLEN (real, 0); i++)
18170 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18172 rtx set = XVECEXP (real, 0, i);
18174 temp = simplify_rtx (SET_SRC (set));
18176 SET_SRC (set) = temp;
18177 temp = simplify_rtx (SET_DEST (set));
18179 SET_DEST (set) = temp;
18180 if (GET_CODE (SET_DEST (set)) == MEM)
18182 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18184 XEXP (SET_DEST (set), 0) = temp;
18186 RTX_FRAME_RELATED_P (set) = 1;
18190 RTX_FRAME_RELATED_P (insn) = 1;
18191 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18194 /* Returns an insn that has a vrsave set operation with the
18195 appropriate CLOBBERs. */
18198 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18201 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18202 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18205 = gen_rtx_SET (VOIDmode,
18207 gen_rtx_UNSPEC_VOLATILE (SImode,
18208 gen_rtvec (2, reg, vrsave),
18209 UNSPECV_SET_VRSAVE));
18213 /* We need to clobber the registers in the mask so the scheduler
18214 does not move sets to VRSAVE before sets of AltiVec registers.
18216 However, if the function receives nonlocal gotos, reload will set
18217 all call saved registers live. We will end up with:
18219 (set (reg 999) (mem))
18220 (parallel [ (set (reg vrsave) (unspec blah))
18221 (clobber (reg 999))])
18223 The clobber will cause the store into reg 999 to be dead, and
18224 flow will attempt to delete an epilogue insn. In this case, we
18225 need an unspec use/set of the register. */
18227 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18228 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18230 if (!epiloguep || call_used_regs [i])
18231 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18232 gen_rtx_REG (V4SImode, i));
18235 rtx reg = gen_rtx_REG (V4SImode, i);
18238 = gen_rtx_SET (VOIDmode,
18240 gen_rtx_UNSPEC (V4SImode,
18241 gen_rtvec (1, reg), 27));
18245 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18247 for (i = 0; i < nclobs; ++i)
18248 XVECEXP (insn, 0, i) = clobs[i];
18253 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18254 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18257 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18258 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18260 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18261 rtx replacea, replaceb;
18263 int_rtx = GEN_INT (offset);
18265 /* Some cases that need register indexed addressing. */
18266 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18267 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18268 || (TARGET_E500_DOUBLE && mode == DFmode)
18270 && SPE_VECTOR_MODE (mode)
18271 && !SPE_CONST_OFFSET_OK (offset)))
18273 /* Whomever calls us must make sure r11 is available in the
18274 flow path of instructions in the prologue. */
18275 offset_rtx = gen_rtx_REG (Pmode, 11);
18276 emit_move_insn (offset_rtx, int_rtx);
18278 replacea = offset_rtx;
18279 replaceb = int_rtx;
18283 offset_rtx = int_rtx;
18284 replacea = NULL_RTX;
18285 replaceb = NULL_RTX;
18288 reg = gen_rtx_REG (mode, regno);
18289 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18290 mem = gen_frame_mem (mode, addr);
18292 insn = emit_move_insn (mem, reg);
18294 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18297 /* Emit an offset memory reference suitable for a frame store, while
18298 converting to a valid addressing mode. */
18301 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18303 rtx int_rtx, offset_rtx;
18305 int_rtx = GEN_INT (offset);
18307 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18308 || (TARGET_E500_DOUBLE && mode == DFmode))
18310 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18311 emit_move_insn (offset_rtx, int_rtx);
18314 offset_rtx = int_rtx;
18316 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18319 /* Look for user-defined global regs. We should not save and restore these,
18320 and cannot use stmw/lmw if there are any in its range. */
18323 no_global_regs_above (int first, bool gpr)
18326 int last = gpr ? 32 : 64;
18327 for (i = first; i < last; i++)
18328 if (global_regs[i])
18333 #ifndef TARGET_FIX_AND_CONTINUE
18334 #define TARGET_FIX_AND_CONTINUE 0
18337 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18338 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18339 #define LAST_SAVRES_REGISTER 31
18340 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18342 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18344 /* Temporary holding space for an out-of-line register save/restore
18346 static char savres_routine_name[30];
18348 /* Return the name for an out-of-line register save/restore routine.
18349 We are saving/restoring GPRs if GPR is true. */
18352 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18353 bool savep, bool gpr, bool lr)
18355 const char *prefix = "";
18356 const char *suffix = "";
18358 /* Different targets are supposed to define
18359 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18360 routine name could be defined with:
18362 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18364 This is a nice idea in practice, but in reality, things are
18365 complicated in several ways:
18367 - ELF targets have save/restore routines for GPRs.
18369 - SPE targets use different prefixes for 32/64-bit registers, and
18370 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18372 - PPC64 ELF targets have routines for save/restore of GPRs that
18373 differ in what they do with the link register, so having a set
18374 prefix doesn't work. (We only use one of the save routines at
18375 the moment, though.)
18377 - PPC32 elf targets have "exit" versions of the restore routines
18378 that restore the link register and can save some extra space.
18379 These require an extra suffix. (There are also "tail" versions
18380 of the restore routines and "GOT" versions of the save routines,
18381 but we don't generate those at present. Same problems apply,
18384 We deal with all this by synthesizing our own prefix/suffix and
18385 using that for the simple sprintf call shown above. */
18388 /* No floating point saves on the SPE. */
18392 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18394 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18399 else if (DEFAULT_ABI == ABI_V4)
18405 prefix = savep ? "_savegpr_" : "_restgpr_";
18407 prefix = savep ? "_savefpr_" : "_restfpr_";
18412 else if (DEFAULT_ABI == ABI_AIX)
18414 #ifndef POWERPC_LINUX
18415 /* No out-of-line save/restore routines for GPRs on AIX. */
18416 gcc_assert (!TARGET_AIX || !gpr);
18422 ? (lr ? "_savegpr0_" : "_savegpr1_")
18423 : (lr ? "_restgpr0_" : "_restgpr1_"));
18424 #ifdef POWERPC_LINUX
18426 prefix = (savep ? "_savefpr_" : "_restfpr_");
18430 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18431 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18434 else if (DEFAULT_ABI == ABI_DARWIN)
18435 sorry ("Out-of-line save/restore routines not supported on Darwin");
18437 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18439 return savres_routine_name;
18442 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18443 We are saving/restoring GPRs if GPR is true. */
18446 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18449 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18451 int select = ((savep ? 1 : 0) << 2
18453 /* On the SPE, we never have any FPRs, but we do have
18454 32/64-bit versions of the routines. */
18455 ? (info->spe_64bit_regs_used ? 1 : 0)
18456 : (gpr ? 1 : 0)) << 1)
18459 /* Don't generate bogus routine names. */
18460 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18461 && regno <= LAST_SAVRES_REGISTER);
18463 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18469 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18471 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18472 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18473 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18479 /* Emit a sequence of insns, including a stack tie if needed, for
18480 resetting the stack pointer. If SAVRES is true, then don't reset the
18481 stack pointer, but move the base of the frame into r11 for use by
18482 out-of-line register restore routines. */
18485 rs6000_emit_stack_reset (rs6000_stack_t *info,
18486 rtx sp_reg_rtx, rtx frame_reg_rtx,
18487 int sp_offset, bool savres)
18489 /* This blockage is needed so that sched doesn't decide to move
18490 the sp change before the register restores. */
18491 if (frame_reg_rtx != sp_reg_rtx
18493 && info->spe_64bit_regs_used != 0
18494 && info->first_gp_reg_save != 32))
18495 rs6000_emit_stack_tie ();
18497 if (frame_reg_rtx != sp_reg_rtx)
18499 if (sp_offset != 0)
18501 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18502 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18503 GEN_INT (sp_offset)));
18506 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18508 else if (sp_offset != 0)
18510 /* If we are restoring registers out-of-line, we will be using the
18511 "exit" variants of the restore routines, which will reset the
18512 stack for us. But we do need to point r11 into the right place
18513 for those routines. */
18514 rtx dest_reg = (savres
18515 ? gen_rtx_REG (Pmode, 11)
18518 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18519 GEN_INT (sp_offset)));
18526 /* Construct a parallel rtx describing the effect of a call to an
18527 out-of-line register save/restore routine. */
18530 rs6000_make_savres_rtx (rs6000_stack_t *info,
18531 rtx frame_reg_rtx, int save_area_offset,
18532 enum machine_mode reg_mode,
18533 bool savep, bool gpr, bool lr)
18536 int offset, start_reg, end_reg, n_regs;
18537 int reg_size = GET_MODE_SIZE (reg_mode);
18543 ? info->first_gp_reg_save
18544 : info->first_fp_reg_save);
18545 end_reg = gpr ? 32 : 64;
18546 n_regs = end_reg - start_reg;
18547 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18550 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18552 RTVEC_ELT (p, offset++)
18553 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18555 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18556 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18557 RTVEC_ELT (p, offset++)
18558 = gen_rtx_USE (VOIDmode,
18559 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18563 for (i = 0; i < end_reg - start_reg; i++)
18565 rtx addr, reg, mem;
18566 reg = gen_rtx_REG (reg_mode, start_reg + i);
18567 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18568 GEN_INT (save_area_offset + reg_size*i));
18569 mem = gen_frame_mem (reg_mode, addr);
18571 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18573 savep ? reg : mem);
18578 rtx addr, reg, mem;
18579 reg = gen_rtx_REG (Pmode, 0);
18580 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18581 GEN_INT (info->lr_save_offset));
18582 mem = gen_frame_mem (Pmode, addr);
18583 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18586 return gen_rtx_PARALLEL (VOIDmode, p);
18589 /* Determine whether the gp REG is really used. */
18592 rs6000_reg_live_or_pic_offset_p (int reg)
18594 return ((df_regs_ever_live_p (reg)
18595 && (!call_used_regs[reg]
18596 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18597 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18598 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18599 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18600 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18604 SAVRES_MULTIPLE = 0x1,
18605 SAVRES_INLINE_FPRS = 0x2,
18606 SAVRES_INLINE_GPRS = 0x4,
18607 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18608 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18609 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18612 /* Determine the strategy for savings/restoring registers. */
18615 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18616 int using_static_chain_p, int sibcall)
18618 bool using_multiple_p;
18620 bool savres_fprs_inline;
18621 bool savres_gprs_inline;
18622 bool noclobber_global_gprs
18623 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18626 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18627 && (!TARGET_SPE_ABI
18628 || info->spe_64bit_regs_used == 0)
18629 && info->first_gp_reg_save < 31
18630 && noclobber_global_gprs);
18631 /* Don't bother to try to save things out-of-line if r11 is occupied
18632 by the static chain. It would require too much fiddling and the
18633 static chain is rarely used anyway. */
18634 common = (using_static_chain_p
18636 || crtl->calls_eh_return
18637 || !info->lr_save_p
18638 || cfun->machine->ra_need_lr
18639 || info->total_size > 32767);
18640 savres_fprs_inline = (common
18641 || info->first_fp_reg_save == 64
18642 || !no_global_regs_above (info->first_fp_reg_save,
18644 /* The out-of-line FP routines use
18645 double-precision stores; we can't use those
18646 routines if we don't have such stores. */
18647 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18648 || FP_SAVE_INLINE (info->first_fp_reg_save));
18649 savres_gprs_inline = (common
18650 /* Saving CR interferes with the exit routines
18651 used on the SPE, so just punt here. */
18654 && info->spe_64bit_regs_used != 0
18655 && info->cr_save_p != 0)
18656 || info->first_gp_reg_save == 32
18657 || !noclobber_global_gprs
18658 || GP_SAVE_INLINE (info->first_gp_reg_save));
18661 /* If we are going to use store multiple, then don't even bother
18662 with the out-of-line routines, since the store-multiple instruction
18663 will always be smaller. */
18664 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18667 /* The situation is more complicated with load multiple. We'd
18668 prefer to use the out-of-line routines for restores, since the
18669 "exit" out-of-line routines can handle the restore of LR and
18670 the frame teardown. But we can only use the out-of-line
18671 routines if we know that we've used store multiple or
18672 out-of-line routines in the prologue, i.e. if we've saved all
18673 the registers from first_gp_reg_save. Otherwise, we risk
18674 loading garbage from the stack. Furthermore, we can only use
18675 the "exit" out-of-line gpr restore if we haven't saved any
18677 bool saved_all = !savres_gprs_inline || using_multiple_p;
18679 if (saved_all && info->first_fp_reg_save != 64)
18680 /* We can't use the exit routine; use load multiple if it's
18682 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18685 strategy = (using_multiple_p
18686 | (savres_fprs_inline << 1)
18687 | (savres_gprs_inline << 2));
18688 #ifdef POWERPC_LINUX
18691 if (!savres_fprs_inline)
18692 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18693 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18694 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18697 if (TARGET_AIX && !savres_fprs_inline)
18698 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18703 /* Emit function prologue as insns. */
18706 rs6000_emit_prologue (void)
18708 rs6000_stack_t *info = rs6000_stack_info ();
18709 enum machine_mode reg_mode = Pmode;
18710 int reg_size = TARGET_32BIT ? 4 : 8;
18711 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18712 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18713 rtx frame_reg_rtx = sp_reg_rtx;
18714 rtx cr_save_rtx = NULL_RTX;
18717 int saving_FPRs_inline;
18718 int saving_GPRs_inline;
18719 int using_store_multiple;
18720 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18721 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18722 && call_used_regs[STATIC_CHAIN_REGNUM]);
18723 HOST_WIDE_INT sp_offset = 0;
18725 if (TARGET_FIX_AND_CONTINUE)
18727 /* gdb on darwin arranges to forward a function from the old
18728 address by modifying the first 5 instructions of the function
18729 to branch to the overriding function. This is necessary to
18730 permit function pointers that point to the old function to
18731 actually forward to the new function. */
18732 emit_insn (gen_nop ());
18733 emit_insn (gen_nop ());
18734 emit_insn (gen_nop ());
18735 emit_insn (gen_nop ());
18736 emit_insn (gen_nop ());
18739 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18741 reg_mode = V2SImode;
18745 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18746 /*static_chain_p=*/using_static_chain_p,
18748 using_store_multiple = strategy & SAVRES_MULTIPLE;
18749 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18750 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18752 /* For V.4, update stack before we do any saving and set back pointer. */
18753 if (! WORLD_SAVE_P (info)
18755 && (DEFAULT_ABI == ABI_V4
18756 || crtl->calls_eh_return))
18758 bool need_r11 = (TARGET_SPE
18759 ? (!saving_GPRs_inline
18760 && info->spe_64bit_regs_used == 0)
18761 : (!saving_FPRs_inline || !saving_GPRs_inline));
18762 if (info->total_size < 32767)
18763 sp_offset = info->total_size;
18765 frame_reg_rtx = (need_r11
18766 ? gen_rtx_REG (Pmode, 11)
18768 rs6000_emit_allocate_stack (info->total_size,
18769 (frame_reg_rtx != sp_reg_rtx
18770 && (info->cr_save_p
18772 || info->first_fp_reg_save < 64
18773 || info->first_gp_reg_save < 32
18776 if (frame_reg_rtx != sp_reg_rtx)
18777 rs6000_emit_stack_tie ();
18780 /* Handle world saves specially here. */
18781 if (WORLD_SAVE_P (info))
18788 /* save_world expects lr in r0. */
18789 reg0 = gen_rtx_REG (Pmode, 0);
18790 if (info->lr_save_p)
18792 insn = emit_move_insn (reg0,
18793 gen_rtx_REG (Pmode, LR_REGNO));
18794 RTX_FRAME_RELATED_P (insn) = 1;
18797 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18798 assumptions about the offsets of various bits of the stack
18800 gcc_assert (info->gp_save_offset == -220
18801 && info->fp_save_offset == -144
18802 && info->lr_save_offset == 8
18803 && info->cr_save_offset == 4
18806 && (!crtl->calls_eh_return
18807 || info->ehrd_offset == -432)
18808 && info->vrsave_save_offset == -224
18809 && info->altivec_save_offset == -416);
18811 treg = gen_rtx_REG (SImode, 11);
18812 emit_move_insn (treg, GEN_INT (-info->total_size));
18814 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18815 in R11. It also clobbers R12, so beware! */
18817 /* Preserve CR2 for save_world prologues */
18819 sz += 32 - info->first_gp_reg_save;
18820 sz += 64 - info->first_fp_reg_save;
18821 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18822 p = rtvec_alloc (sz);
18824 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18825 gen_rtx_REG (SImode,
18827 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18828 gen_rtx_SYMBOL_REF (Pmode,
18830 /* We do floats first so that the instruction pattern matches
18832 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18834 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18835 ? DFmode : SFmode),
18836 info->first_fp_reg_save + i);
18837 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18838 GEN_INT (info->fp_save_offset
18839 + sp_offset + 8 * i));
18840 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18841 ? DFmode : SFmode), addr);
18843 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18845 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18847 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18848 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18849 GEN_INT (info->altivec_save_offset
18850 + sp_offset + 16 * i));
18851 rtx mem = gen_frame_mem (V4SImode, addr);
18853 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18855 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18857 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18858 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18859 GEN_INT (info->gp_save_offset
18860 + sp_offset + reg_size * i));
18861 rtx mem = gen_frame_mem (reg_mode, addr);
18863 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18867 /* CR register traditionally saved as CR2. */
18868 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18869 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18870 GEN_INT (info->cr_save_offset
18872 rtx mem = gen_frame_mem (reg_mode, addr);
18874 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18876 /* Explain about use of R0. */
18877 if (info->lr_save_p)
18879 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18880 GEN_INT (info->lr_save_offset
18882 rtx mem = gen_frame_mem (reg_mode, addr);
18884 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18886 /* Explain what happens to the stack pointer. */
18888 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18889 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18892 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18893 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18894 treg, GEN_INT (-info->total_size));
18895 sp_offset = info->total_size;
18898 /* If we use the link register, get it into r0. */
18899 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18901 rtx addr, reg, mem;
18903 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18904 gen_rtx_REG (Pmode, LR_REGNO));
18905 RTX_FRAME_RELATED_P (insn) = 1;
18907 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18908 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18910 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18911 GEN_INT (info->lr_save_offset + sp_offset));
18912 reg = gen_rtx_REG (Pmode, 0);
18913 mem = gen_rtx_MEM (Pmode, addr);
18914 /* This should not be of rs6000_sr_alias_set, because of
18915 __builtin_return_address. */
18917 insn = emit_move_insn (mem, reg);
18918 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18919 NULL_RTX, NULL_RTX);
18923 /* If we need to save CR, put it into r12 or r11. */
18924 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18929 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18931 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18932 RTX_FRAME_RELATED_P (insn) = 1;
18933 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18934 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18935 But that's OK. All we have to do is specify that _one_ condition
18936 code register is saved in this stack slot. The thrower's epilogue
18937 will then restore all the call-saved registers.
18938 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18939 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18940 gen_rtx_REG (SImode, CR2_REGNO));
18941 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18944 /* Do any required saving of fpr's. If only one or two to save, do
18945 it ourselves. Otherwise, call function. */
18946 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18949 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18950 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18951 && ! call_used_regs[info->first_fp_reg_save+i]))
18952 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18953 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18955 info->first_fp_reg_save + i,
18956 info->fp_save_offset + sp_offset + 8 * i,
18959 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18963 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18964 info->fp_save_offset + sp_offset,
18966 /*savep=*/true, /*gpr=*/false,
18968 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18970 insn = emit_insn (par);
18971 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18972 NULL_RTX, NULL_RTX);
18975 /* Save GPRs. This is done as a PARALLEL if we are using
18976 the store-multiple instructions. */
18977 if (!WORLD_SAVE_P (info)
18979 && info->spe_64bit_regs_used != 0
18980 && info->first_gp_reg_save != 32)
18983 rtx spe_save_area_ptr;
18985 /* Determine whether we can address all of the registers that need
18986 to be saved with an offset from the stack pointer that fits in
18987 the small const field for SPE memory instructions. */
18988 int spe_regs_addressable_via_sp
18989 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18990 + (32 - info->first_gp_reg_save - 1) * reg_size)
18991 && saving_GPRs_inline);
18994 if (spe_regs_addressable_via_sp)
18996 spe_save_area_ptr = frame_reg_rtx;
18997 spe_offset = info->spe_gp_save_offset + sp_offset;
19001 /* Make r11 point to the start of the SPE save area. We need
19002 to be careful here if r11 is holding the static chain. If
19003 it is, then temporarily save it in r0. We would use r0 as
19004 our base register here, but using r0 as a base register in
19005 loads and stores means something different from what we
19007 int ool_adjust = (saving_GPRs_inline
19009 : (info->first_gp_reg_save
19010 - (FIRST_SAVRES_REGISTER+1))*8);
19011 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19012 + sp_offset - ool_adjust);
19014 if (using_static_chain_p)
19016 rtx r0 = gen_rtx_REG (Pmode, 0);
19017 gcc_assert (info->first_gp_reg_save > 11);
19019 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19022 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19023 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19025 GEN_INT (offset)));
19026 /* We need to make sure the move to r11 gets noted for
19027 properly outputting unwind information. */
19028 if (!saving_GPRs_inline)
19029 rs6000_frame_related (insn, frame_reg_rtx, offset,
19030 NULL_RTX, NULL_RTX);
19034 if (saving_GPRs_inline)
19036 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19037 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19039 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19040 rtx offset, addr, mem;
19042 /* We're doing all this to ensure that the offset fits into
19043 the immediate offset of 'evstdd'. */
19044 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19046 offset = GEN_INT (reg_size * i + spe_offset);
19047 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19048 mem = gen_rtx_MEM (V2SImode, addr);
19050 insn = emit_move_insn (mem, reg);
19052 rs6000_frame_related (insn, spe_save_area_ptr,
19053 info->spe_gp_save_offset
19054 + sp_offset + reg_size * i,
19055 offset, const0_rtx);
19062 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19064 /*savep=*/true, /*gpr=*/true,
19066 insn = emit_insn (par);
19067 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19068 NULL_RTX, NULL_RTX);
19072 /* Move the static chain pointer back. */
19073 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19074 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19076 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19080 /* Need to adjust r11 (r12) if we saved any FPRs. */
19081 if (info->first_fp_reg_save != 64)
19083 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19085 rtx offset = GEN_INT (sp_offset
19086 + (-8 * (64-info->first_fp_reg_save)));
19087 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19090 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19091 info->gp_save_offset + sp_offset,
19093 /*savep=*/true, /*gpr=*/true,
19095 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19097 insn = emit_insn (par);
19098 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19099 NULL_RTX, NULL_RTX);
19101 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19105 p = rtvec_alloc (32 - info->first_gp_reg_save);
19106 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19108 rtx addr, reg, mem;
19109 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19110 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19111 GEN_INT (info->gp_save_offset
19114 mem = gen_frame_mem (reg_mode, addr);
19116 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19118 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19119 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19120 NULL_RTX, NULL_RTX);
19122 else if (!WORLD_SAVE_P (info))
19125 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19126 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19128 rtx addr, reg, mem;
19129 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19131 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19132 GEN_INT (info->gp_save_offset
19135 mem = gen_frame_mem (reg_mode, addr);
19137 insn = emit_move_insn (mem, reg);
19138 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19139 NULL_RTX, NULL_RTX);
19143 /* ??? There's no need to emit actual instructions here, but it's the
19144 easiest way to get the frame unwind information emitted. */
19145 if (crtl->calls_eh_return)
19147 unsigned int i, regno;
19149 /* In AIX ABI we need to pretend we save r2 here. */
19152 rtx addr, reg, mem;
19154 reg = gen_rtx_REG (reg_mode, 2);
19155 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19156 GEN_INT (sp_offset + 5 * reg_size));
19157 mem = gen_frame_mem (reg_mode, addr);
19159 insn = emit_move_insn (mem, reg);
19160 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19161 NULL_RTX, NULL_RTX);
19162 PATTERN (insn) = gen_blockage ();
19167 regno = EH_RETURN_DATA_REGNO (i);
19168 if (regno == INVALID_REGNUM)
19171 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19172 info->ehrd_offset + sp_offset
19173 + reg_size * (int) i,
19178 /* Save CR if we use any that must be preserved. */
19179 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19181 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19182 GEN_INT (info->cr_save_offset + sp_offset));
19183 rtx mem = gen_frame_mem (SImode, addr);
19184 /* See the large comment above about why CR2_REGNO is used. */
19185 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19187 /* If r12 was used to hold the original sp, copy cr into r0 now
19189 if (REGNO (frame_reg_rtx) == 12)
19193 cr_save_rtx = gen_rtx_REG (SImode, 0);
19194 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19195 RTX_FRAME_RELATED_P (insn) = 1;
19196 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19197 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19199 insn = emit_move_insn (mem, cr_save_rtx);
19201 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19202 NULL_RTX, NULL_RTX);
19205 /* Update stack and set back pointer unless this is V.4,
19206 for which it was done previously. */
19207 if (!WORLD_SAVE_P (info) && info->push_p
19208 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19210 if (info->total_size < 32767)
19211 sp_offset = info->total_size;
19213 frame_reg_rtx = frame_ptr_rtx;
19214 rs6000_emit_allocate_stack (info->total_size,
19215 (frame_reg_rtx != sp_reg_rtx
19216 && ((info->altivec_size != 0)
19217 || (info->vrsave_mask != 0)
19220 if (frame_reg_rtx != sp_reg_rtx)
19221 rs6000_emit_stack_tie ();
19224 /* Set frame pointer, if needed. */
19225 if (frame_pointer_needed)
19227 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19229 RTX_FRAME_RELATED_P (insn) = 1;
19232 /* Save AltiVec registers if needed. Save here because the red zone does
19233 not include AltiVec registers. */
19234 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19238 /* There should be a non inline version of this, for when we
19239 are saving lots of vector registers. */
19240 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19241 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19243 rtx areg, savereg, mem;
19246 offset = info->altivec_save_offset + sp_offset
19247 + 16 * (i - info->first_altivec_reg_save);
19249 savereg = gen_rtx_REG (V4SImode, i);
19251 areg = gen_rtx_REG (Pmode, 0);
19252 emit_move_insn (areg, GEN_INT (offset));
19254 /* AltiVec addressing mode is [reg+reg]. */
19255 mem = gen_frame_mem (V4SImode,
19256 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19258 insn = emit_move_insn (mem, savereg);
19260 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19261 areg, GEN_INT (offset));
19265 /* VRSAVE is a bit vector representing which AltiVec registers
19266 are used. The OS uses this to determine which vector
19267 registers to save on a context switch. We need to save
19268 VRSAVE on the stack frame, add whatever AltiVec registers we
19269 used in this function, and do the corresponding magic in the
19272 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19273 && info->vrsave_mask != 0)
19275 rtx reg, mem, vrsave;
19278 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19279 as frame_reg_rtx and r11 as the static chain pointer for
19280 nested functions. */
19281 reg = gen_rtx_REG (SImode, 0);
19282 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19284 emit_insn (gen_get_vrsave_internal (reg));
19286 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19288 if (!WORLD_SAVE_P (info))
19291 offset = info->vrsave_save_offset + sp_offset;
19292 mem = gen_frame_mem (SImode,
19293 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19294 GEN_INT (offset)));
19295 insn = emit_move_insn (mem, reg);
19298 /* Include the registers in the mask. */
19299 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19301 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19304 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19305 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19306 || (DEFAULT_ABI == ABI_V4
19307 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19308 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19310 /* If emit_load_toc_table will use the link register, we need to save
19311 it. We use R12 for this purpose because emit_load_toc_table
19312 can use register 0. This allows us to use a plain 'blr' to return
19313 from the procedure more often. */
19314 int save_LR_around_toc_setup = (TARGET_ELF
19315 && DEFAULT_ABI != ABI_AIX
19317 && ! info->lr_save_p
19318 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19319 if (save_LR_around_toc_setup)
19321 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19323 insn = emit_move_insn (frame_ptr_rtx, lr);
19324 RTX_FRAME_RELATED_P (insn) = 1;
19326 rs6000_emit_load_toc_table (TRUE);
19328 insn = emit_move_insn (lr, frame_ptr_rtx);
19329 RTX_FRAME_RELATED_P (insn) = 1;
19332 rs6000_emit_load_toc_table (TRUE);
19336 if (DEFAULT_ABI == ABI_DARWIN
19337 && flag_pic && crtl->uses_pic_offset_table)
19339 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19340 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19342 /* Save and restore LR locally around this call (in R0). */
19343 if (!info->lr_save_p)
19344 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19346 emit_insn (gen_load_macho_picbase (src));
19348 emit_move_insn (gen_rtx_REG (Pmode,
19349 RS6000_PIC_OFFSET_TABLE_REGNUM),
19352 if (!info->lr_save_p)
19353 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19358 /* Write function prologue. */
19361 rs6000_output_function_prologue (FILE *file,
19362 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19364 rs6000_stack_t *info = rs6000_stack_info ();
19366 if (TARGET_DEBUG_STACK)
19367 debug_stack_info (info);
19369 /* Write .extern for any function we will call to save and restore
19371 if (info->first_fp_reg_save < 64
19372 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19375 int regno = info->first_fp_reg_save - 32;
19377 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19378 /*gpr=*/false, /*lr=*/false);
19379 fprintf (file, "\t.extern %s\n", name);
19381 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19382 /*gpr=*/false, /*lr=*/true);
19383 fprintf (file, "\t.extern %s\n", name);
19386 /* Write .extern for AIX common mode routines, if needed. */
19387 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19389 fputs ("\t.extern __mulh\n", file);
19390 fputs ("\t.extern __mull\n", file);
19391 fputs ("\t.extern __divss\n", file);
19392 fputs ("\t.extern __divus\n", file);
19393 fputs ("\t.extern __quoss\n", file);
19394 fputs ("\t.extern __quous\n", file);
19395 common_mode_defined = 1;
19398 if (! HAVE_prologue)
19404 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19405 the "toplevel" insn chain. */
19406 emit_note (NOTE_INSN_DELETED);
19407 rs6000_emit_prologue ();
19408 emit_note (NOTE_INSN_DELETED);
19410 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19414 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19416 INSN_ADDRESSES_NEW (insn, addr);
19421 prologue = get_insns ();
19424 if (TARGET_DEBUG_STACK)
19425 debug_rtx_list (prologue, 100);
19427 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19431 rs6000_pic_labelno++;
19434 /* Non-zero if vmx regs are restored before the frame pop, zero if
19435 we restore after the pop when possible. */
19436 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19438 /* Reload CR from REG. */
19441 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19446 if (using_mfcr_multiple)
19448 for (i = 0; i < 8; i++)
19449 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19451 gcc_assert (count);
19454 if (using_mfcr_multiple && count > 1)
19459 p = rtvec_alloc (count);
19462 for (i = 0; i < 8; i++)
19463 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19465 rtvec r = rtvec_alloc (2);
19466 RTVEC_ELT (r, 0) = reg;
19467 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19468 RTVEC_ELT (p, ndx) =
19469 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19470 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19473 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19474 gcc_assert (ndx == count);
19477 for (i = 0; i < 8; i++)
19478 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19480 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19486 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19487 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19488 below stack pointer not cloberred by signals. */
19491 offset_below_red_zone_p (HOST_WIDE_INT offset)
19493 return offset < (DEFAULT_ABI == ABI_V4
19495 : TARGET_32BIT ? -220 : -288);
19498 /* Emit function epilogue as insns. */
19501 rs6000_emit_epilogue (int sibcall)
19503 rs6000_stack_t *info;
19504 int restoring_GPRs_inline;
19505 int restoring_FPRs_inline;
19506 int using_load_multiple;
19507 int using_mtcr_multiple;
19508 int use_backchain_to_restore_sp;
19512 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19513 rtx frame_reg_rtx = sp_reg_rtx;
19514 rtx cfa_restores = NULL_RTX;
19516 rtx cr_save_reg = NULL_RTX;
19517 enum machine_mode reg_mode = Pmode;
19518 int reg_size = TARGET_32BIT ? 4 : 8;
19521 info = rs6000_stack_info ();
19523 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19525 reg_mode = V2SImode;
19529 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19530 /*static_chain_p=*/0, sibcall);
19531 using_load_multiple = strategy & SAVRES_MULTIPLE;
19532 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19533 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19534 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19535 || rs6000_cpu == PROCESSOR_PPC603
19536 || rs6000_cpu == PROCESSOR_PPC750
19538 /* Restore via the backchain when we have a large frame, since this
19539 is more efficient than an addis, addi pair. The second condition
19540 here will not trigger at the moment; We don't actually need a
19541 frame pointer for alloca, but the generic parts of the compiler
19542 give us one anyway. */
19543 use_backchain_to_restore_sp = (info->total_size > 32767
19544 || info->total_size
19545 + (info->lr_save_p ? info->lr_save_offset : 0)
19547 || (cfun->calls_alloca
19548 && !frame_pointer_needed));
19549 restore_lr = (info->lr_save_p
19550 && (restoring_FPRs_inline
19551 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19552 && (restoring_GPRs_inline
19553 || info->first_fp_reg_save < 64));
19555 if (WORLD_SAVE_P (info))
19559 const char *alloc_rname;
19562 /* eh_rest_world_r10 will return to the location saved in the LR
19563 stack slot (which is not likely to be our caller.)
19564 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19565 rest_world is similar, except any R10 parameter is ignored.
19566 The exception-handling stuff that was here in 2.95 is no
19567 longer necessary. */
19571 + 32 - info->first_gp_reg_save
19572 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19573 + 63 + 1 - info->first_fp_reg_save);
19575 strcpy (rname, ((crtl->calls_eh_return) ?
19576 "*eh_rest_world_r10" : "*rest_world"));
19577 alloc_rname = ggc_strdup (rname);
19580 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19581 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19582 gen_rtx_REG (Pmode,
19585 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19586 /* The instruction pattern requires a clobber here;
19587 it is shared with the restVEC helper. */
19589 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19592 /* CR register traditionally saved as CR2. */
19593 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19594 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19595 GEN_INT (info->cr_save_offset));
19596 rtx mem = gen_frame_mem (reg_mode, addr);
19598 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19601 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19603 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19604 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19605 GEN_INT (info->gp_save_offset
19607 rtx mem = gen_frame_mem (reg_mode, addr);
19609 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19611 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19613 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19614 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19615 GEN_INT (info->altivec_save_offset
19617 rtx mem = gen_frame_mem (V4SImode, addr);
19619 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19621 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19623 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19624 ? DFmode : SFmode),
19625 info->first_fp_reg_save + i);
19626 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19627 GEN_INT (info->fp_save_offset
19629 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19630 ? DFmode : SFmode), addr);
19632 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19635 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19637 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19639 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19641 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19643 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19644 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19649 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19651 sp_offset = info->total_size;
19653 /* Restore AltiVec registers if we must do so before adjusting the
19655 if (TARGET_ALTIVEC_ABI
19656 && info->altivec_size != 0
19657 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19658 || (DEFAULT_ABI != ABI_V4
19659 && offset_below_red_zone_p (info->altivec_save_offset))))
19663 if (use_backchain_to_restore_sp)
19665 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19666 emit_move_insn (frame_reg_rtx,
19667 gen_rtx_MEM (Pmode, sp_reg_rtx));
19670 else if (frame_pointer_needed)
19671 frame_reg_rtx = hard_frame_pointer_rtx;
19673 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19674 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19676 rtx addr, areg, mem, reg;
19678 areg = gen_rtx_REG (Pmode, 0);
19680 (areg, GEN_INT (info->altivec_save_offset
19682 + 16 * (i - info->first_altivec_reg_save)));
19684 /* AltiVec addressing mode is [reg+reg]. */
19685 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19686 mem = gen_frame_mem (V4SImode, addr);
19688 reg = gen_rtx_REG (V4SImode, i);
19689 emit_move_insn (reg, mem);
19690 if (offset_below_red_zone_p (info->altivec_save_offset
19691 + (i - info->first_altivec_reg_save)
19693 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19698 /* Restore VRSAVE if we must do so before adjusting the stack. */
19700 && TARGET_ALTIVEC_VRSAVE
19701 && info->vrsave_mask != 0
19702 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19703 || (DEFAULT_ABI != ABI_V4
19704 && offset_below_red_zone_p (info->vrsave_save_offset))))
19706 rtx addr, mem, reg;
19708 if (frame_reg_rtx == sp_reg_rtx)
19710 if (use_backchain_to_restore_sp)
19712 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19713 emit_move_insn (frame_reg_rtx,
19714 gen_rtx_MEM (Pmode, sp_reg_rtx));
19717 else if (frame_pointer_needed)
19718 frame_reg_rtx = hard_frame_pointer_rtx;
19721 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19722 GEN_INT (info->vrsave_save_offset + sp_offset));
19723 mem = gen_frame_mem (SImode, addr);
19724 reg = gen_rtx_REG (SImode, 12);
19725 emit_move_insn (reg, mem);
19727 emit_insn (generate_set_vrsave (reg, info, 1));
19731 /* If we have a large stack frame, restore the old stack pointer
19732 using the backchain. */
19733 if (use_backchain_to_restore_sp)
19735 if (frame_reg_rtx == sp_reg_rtx)
19737 /* Under V.4, don't reset the stack pointer until after we're done
19738 loading the saved registers. */
19739 if (DEFAULT_ABI == ABI_V4)
19740 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19742 insn = emit_move_insn (frame_reg_rtx,
19743 gen_rtx_MEM (Pmode, sp_reg_rtx));
19746 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19747 && DEFAULT_ABI == ABI_V4)
19748 /* frame_reg_rtx has been set up by the altivec restore. */
19752 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19753 frame_reg_rtx = sp_reg_rtx;
19756 /* If we have a frame pointer, we can restore the old stack pointer
19758 else if (frame_pointer_needed)
19760 frame_reg_rtx = sp_reg_rtx;
19761 if (DEFAULT_ABI == ABI_V4)
19762 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19764 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19765 GEN_INT (info->total_size)));
19768 else if (info->push_p
19769 && DEFAULT_ABI != ABI_V4
19770 && !crtl->calls_eh_return)
19772 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19773 GEN_INT (info->total_size)));
19776 if (insn && frame_reg_rtx == sp_reg_rtx)
19780 REG_NOTES (insn) = cfa_restores;
19781 cfa_restores = NULL_RTX;
19783 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19784 RTX_FRAME_RELATED_P (insn) = 1;
19787 /* Restore AltiVec registers if we have not done so already. */
19788 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19789 && TARGET_ALTIVEC_ABI
19790 && info->altivec_size != 0
19791 && (DEFAULT_ABI == ABI_V4
19792 || !offset_below_red_zone_p (info->altivec_save_offset)))
19796 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19797 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19799 rtx addr, areg, mem, reg;
19801 areg = gen_rtx_REG (Pmode, 0);
19803 (areg, GEN_INT (info->altivec_save_offset
19805 + 16 * (i - info->first_altivec_reg_save)));
19807 /* AltiVec addressing mode is [reg+reg]. */
19808 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19809 mem = gen_frame_mem (V4SImode, addr);
19811 reg = gen_rtx_REG (V4SImode, i);
19812 emit_move_insn (reg, mem);
19813 if (DEFAULT_ABI == ABI_V4)
19814 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19819 /* Restore VRSAVE if we have not done so already. */
19820 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19822 && TARGET_ALTIVEC_VRSAVE
19823 && info->vrsave_mask != 0
19824 && (DEFAULT_ABI == ABI_V4
19825 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19827 rtx addr, mem, reg;
19829 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19830 GEN_INT (info->vrsave_save_offset + sp_offset));
19831 mem = gen_frame_mem (SImode, addr);
19832 reg = gen_rtx_REG (SImode, 12);
19833 emit_move_insn (reg, mem);
19835 emit_insn (generate_set_vrsave (reg, info, 1));
19838 /* Get the old lr if we saved it. If we are restoring registers
19839 out-of-line, then the out-of-line routines can do this for us. */
19840 if (restore_lr && restoring_GPRs_inline)
19842 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19843 info->lr_save_offset + sp_offset);
19845 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19848 /* Get the old cr if we saved it. */
19849 if (info->cr_save_p)
19851 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19852 GEN_INT (info->cr_save_offset + sp_offset));
19853 rtx mem = gen_frame_mem (SImode, addr);
19855 cr_save_reg = gen_rtx_REG (SImode,
19856 DEFAULT_ABI == ABI_AIX
19857 && !restoring_GPRs_inline
19858 && info->first_fp_reg_save < 64
19860 emit_move_insn (cr_save_reg, mem);
19863 /* Set LR here to try to overlap restores below. LR is always saved
19864 above incoming stack, so it never needs REG_CFA_RESTORE. */
19865 if (restore_lr && restoring_GPRs_inline)
19866 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19867 gen_rtx_REG (Pmode, 0));
19869 /* Load exception handler data registers, if needed. */
19870 if (crtl->calls_eh_return)
19872 unsigned int i, regno;
19876 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19877 GEN_INT (sp_offset + 5 * reg_size));
19878 rtx mem = gen_frame_mem (reg_mode, addr);
19880 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19887 regno = EH_RETURN_DATA_REGNO (i);
19888 if (regno == INVALID_REGNUM)
19891 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19892 info->ehrd_offset + sp_offset
19893 + reg_size * (int) i);
19895 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19899 /* Restore GPRs. This is done as a PARALLEL if we are using
19900 the load-multiple instructions. */
19902 && info->spe_64bit_regs_used != 0
19903 && info->first_gp_reg_save != 32)
19905 /* Determine whether we can address all of the registers that need
19906 to be saved with an offset from the stack pointer that fits in
19907 the small const field for SPE memory instructions. */
19908 int spe_regs_addressable_via_sp
19909 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19910 + (32 - info->first_gp_reg_save - 1) * reg_size)
19911 && restoring_GPRs_inline);
19914 if (spe_regs_addressable_via_sp)
19915 spe_offset = info->spe_gp_save_offset + sp_offset;
19918 rtx old_frame_reg_rtx = frame_reg_rtx;
19919 /* Make r11 point to the start of the SPE save area. We worried about
19920 not clobbering it when we were saving registers in the prologue.
19921 There's no need to worry here because the static chain is passed
19922 anew to every function. */
19923 int ool_adjust = (restoring_GPRs_inline
19925 : (info->first_gp_reg_save
19926 - (FIRST_SAVRES_REGISTER+1))*8);
19928 if (frame_reg_rtx == sp_reg_rtx)
19929 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19930 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19931 GEN_INT (info->spe_gp_save_offset
19934 /* Keep the invariant that frame_reg_rtx + sp_offset points
19935 at the top of the stack frame. */
19936 sp_offset = -info->spe_gp_save_offset;
19941 if (restoring_GPRs_inline)
19943 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19944 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19946 rtx offset, addr, mem, reg;
19948 /* We're doing all this to ensure that the immediate offset
19949 fits into the immediate field of 'evldd'. */
19950 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19952 offset = GEN_INT (spe_offset + reg_size * i);
19953 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19954 mem = gen_rtx_MEM (V2SImode, addr);
19955 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19957 insn = emit_move_insn (reg, mem);
19958 if (DEFAULT_ABI == ABI_V4)
19960 if (frame_pointer_needed
19961 && info->first_gp_reg_save + i
19962 == HARD_FRAME_POINTER_REGNUM)
19964 add_reg_note (insn, REG_CFA_DEF_CFA,
19965 plus_constant (frame_reg_rtx,
19967 RTX_FRAME_RELATED_P (insn) = 1;
19970 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19979 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19981 /*savep=*/false, /*gpr=*/true,
19983 emit_jump_insn (par);
19984 /* We don't want anybody else emitting things after we jumped
19989 else if (!restoring_GPRs_inline)
19991 /* We are jumping to an out-of-line function. */
19992 bool can_use_exit = info->first_fp_reg_save == 64;
19995 /* Emit stack reset code if we need it. */
19997 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19998 sp_offset, can_use_exit);
20001 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20004 GEN_INT (sp_offset - info->fp_size)));
20005 if (REGNO (frame_reg_rtx) == 11)
20006 sp_offset += info->fp_size;
20009 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20010 info->gp_save_offset, reg_mode,
20011 /*savep=*/false, /*gpr=*/true,
20012 /*lr=*/can_use_exit);
20016 if (info->cr_save_p)
20018 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20019 if (DEFAULT_ABI == ABI_V4)
20021 = alloc_reg_note (REG_CFA_RESTORE,
20022 gen_rtx_REG (SImode, CR2_REGNO),
20026 emit_jump_insn (par);
20028 /* We don't want anybody else emitting things after we jumped
20033 insn = emit_insn (par);
20034 if (DEFAULT_ABI == ABI_V4)
20036 if (frame_pointer_needed)
20038 add_reg_note (insn, REG_CFA_DEF_CFA,
20039 plus_constant (frame_reg_rtx, sp_offset));
20040 RTX_FRAME_RELATED_P (insn) = 1;
20043 for (i = info->first_gp_reg_save; i < 32; i++)
20045 = alloc_reg_note (REG_CFA_RESTORE,
20046 gen_rtx_REG (reg_mode, i), cfa_restores);
20049 else if (using_load_multiple)
20052 p = rtvec_alloc (32 - info->first_gp_reg_save);
20053 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20055 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20056 GEN_INT (info->gp_save_offset
20059 rtx mem = gen_frame_mem (reg_mode, addr);
20060 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20062 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20063 if (DEFAULT_ABI == ABI_V4)
20064 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20067 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20068 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20070 add_reg_note (insn, REG_CFA_DEF_CFA,
20071 plus_constant (frame_reg_rtx, sp_offset));
20072 RTX_FRAME_RELATED_P (insn) = 1;
20077 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20078 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20080 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20081 GEN_INT (info->gp_save_offset
20084 rtx mem = gen_frame_mem (reg_mode, addr);
20085 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20087 insn = emit_move_insn (reg, mem);
20088 if (DEFAULT_ABI == ABI_V4)
20090 if (frame_pointer_needed
20091 && info->first_gp_reg_save + i
20092 == HARD_FRAME_POINTER_REGNUM)
20094 add_reg_note (insn, REG_CFA_DEF_CFA,
20095 plus_constant (frame_reg_rtx, sp_offset));
20096 RTX_FRAME_RELATED_P (insn) = 1;
20099 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20105 if (restore_lr && !restoring_GPRs_inline)
20107 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20108 info->lr_save_offset + sp_offset);
20110 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20111 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20112 gen_rtx_REG (Pmode, 0));
20115 /* Restore fpr's if we need to do it without calling a function. */
20116 if (restoring_FPRs_inline)
20117 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20118 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20119 && ! call_used_regs[info->first_fp_reg_save+i]))
20121 rtx addr, mem, reg;
20122 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20123 GEN_INT (info->fp_save_offset
20126 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20127 ? DFmode : SFmode), addr);
20128 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20129 ? DFmode : SFmode),
20130 info->first_fp_reg_save + i);
20132 emit_move_insn (reg, mem);
20133 if (DEFAULT_ABI == ABI_V4)
20134 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20138 /* If we saved cr, restore it here. Just those that were used. */
20139 if (info->cr_save_p)
20141 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20142 if (DEFAULT_ABI == ABI_V4)
20144 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20148 /* If this is V.4, unwind the stack pointer after all of the loads
20150 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20151 sp_offset, !restoring_FPRs_inline);
20156 REG_NOTES (insn) = cfa_restores;
20157 cfa_restores = NULL_RTX;
20159 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20160 RTX_FRAME_RELATED_P (insn) = 1;
20163 if (crtl->calls_eh_return)
20165 rtx sa = EH_RETURN_STACKADJ_RTX;
20166 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20172 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20173 if (! restoring_FPRs_inline)
20174 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20176 p = rtvec_alloc (2);
20178 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20179 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20180 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20181 : gen_rtx_CLOBBER (VOIDmode,
20182 gen_rtx_REG (Pmode, 65)));
20184 /* If we have to restore more than two FP registers, branch to the
20185 restore function. It will return to our caller. */
20186 if (! restoring_FPRs_inline)
20191 sym = rs6000_savres_routine_sym (info,
20195 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20196 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20197 gen_rtx_REG (Pmode,
20198 DEFAULT_ABI == ABI_AIX
20200 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20203 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20204 GEN_INT (info->fp_save_offset + 8*i));
20205 mem = gen_frame_mem (DFmode, addr);
20207 RTVEC_ELT (p, i+4) =
20208 gen_rtx_SET (VOIDmode,
20209 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20214 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20218 /* Write function epilogue. */
20221 rs6000_output_function_epilogue (FILE *file,
20222 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20224 if (! HAVE_epilogue)
20226 rtx insn = get_last_insn ();
20227 /* If the last insn was a BARRIER, we don't have to write anything except
20228 the trace table. */
20229 if (GET_CODE (insn) == NOTE)
20230 insn = prev_nonnote_insn (insn);
20231 if (insn == 0 || GET_CODE (insn) != BARRIER)
20233 /* This is slightly ugly, but at least we don't have two
20234 copies of the epilogue-emitting code. */
20237 /* A NOTE_INSN_DELETED is supposed to be at the start
20238 and end of the "toplevel" insn chain. */
20239 emit_note (NOTE_INSN_DELETED);
20240 rs6000_emit_epilogue (FALSE);
20241 emit_note (NOTE_INSN_DELETED);
20243 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20247 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20249 INSN_ADDRESSES_NEW (insn, addr);
20254 if (TARGET_DEBUG_STACK)
20255 debug_rtx_list (get_insns (), 100);
20256 final (get_insns (), file, FALSE);
20262 macho_branch_islands ();
20263 /* Mach-O doesn't support labels at the end of objects, so if
20264 it looks like we might want one, insert a NOP. */
20266 rtx insn = get_last_insn ();
20269 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20270 insn = PREV_INSN (insn);
20274 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20275 fputs ("\tnop\n", file);
20279 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20282 We don't output a traceback table if -finhibit-size-directive was
20283 used. The documentation for -finhibit-size-directive reads
20284 ``don't output a @code{.size} assembler directive, or anything
20285 else that would cause trouble if the function is split in the
20286 middle, and the two halves are placed at locations far apart in
20287 memory.'' The traceback table has this property, since it
20288 includes the offset from the start of the function to the
20289 traceback table itself.
20291 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20292 different traceback table. */
20293 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20294 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20296 const char *fname = NULL;
20297 const char *language_string = lang_hooks.name;
20298 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20300 int optional_tbtab;
20301 rs6000_stack_t *info = rs6000_stack_info ();
20303 if (rs6000_traceback == traceback_full)
20304 optional_tbtab = 1;
20305 else if (rs6000_traceback == traceback_part)
20306 optional_tbtab = 0;
20308 optional_tbtab = !optimize_size && !TARGET_ELF;
20310 if (optional_tbtab)
20312 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20313 while (*fname == '.') /* V.4 encodes . in the name */
20316 /* Need label immediately before tbtab, so we can compute
20317 its offset from the function start. */
20318 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20319 ASM_OUTPUT_LABEL (file, fname);
20322 /* The .tbtab pseudo-op can only be used for the first eight
20323 expressions, since it can't handle the possibly variable
20324 length fields that follow. However, if you omit the optional
20325 fields, the assembler outputs zeros for all optional fields
20326 anyways, giving each variable length field is minimum length
20327 (as defined in sys/debug.h). Thus we can not use the .tbtab
20328 pseudo-op at all. */
20330 /* An all-zero word flags the start of the tbtab, for debuggers
20331 that have to find it by searching forward from the entry
20332 point or from the current pc. */
20333 fputs ("\t.long 0\n", file);
20335 /* Tbtab format type. Use format type 0. */
20336 fputs ("\t.byte 0,", file);
20338 /* Language type. Unfortunately, there does not seem to be any
20339 official way to discover the language being compiled, so we
20340 use language_string.
20341 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20342 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20343 a number, so for now use 9. LTO isn't assigned a number either,
20344 so for now use 0. */
20345 if (! strcmp (language_string, "GNU C")
20346 || ! strcmp (language_string, "GNU GIMPLE"))
20348 else if (! strcmp (language_string, "GNU F77")
20349 || ! strcmp (language_string, "GNU Fortran"))
20351 else if (! strcmp (language_string, "GNU Pascal"))
20353 else if (! strcmp (language_string, "GNU Ada"))
20355 else if (! strcmp (language_string, "GNU C++")
20356 || ! strcmp (language_string, "GNU Objective-C++"))
20358 else if (! strcmp (language_string, "GNU Java"))
20360 else if (! strcmp (language_string, "GNU Objective-C"))
20363 gcc_unreachable ();
20364 fprintf (file, "%d,", i);
20366 /* 8 single bit fields: global linkage (not set for C extern linkage,
20367 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20368 from start of procedure stored in tbtab, internal function, function
20369 has controlled storage, function has no toc, function uses fp,
20370 function logs/aborts fp operations. */
20371 /* Assume that fp operations are used if any fp reg must be saved. */
20372 fprintf (file, "%d,",
20373 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20375 /* 6 bitfields: function is interrupt handler, name present in
20376 proc table, function calls alloca, on condition directives
20377 (controls stack walks, 3 bits), saves condition reg, saves
20379 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20380 set up as a frame pointer, even when there is no alloca call. */
20381 fprintf (file, "%d,",
20382 ((optional_tbtab << 6)
20383 | ((optional_tbtab & frame_pointer_needed) << 5)
20384 | (info->cr_save_p << 1)
20385 | (info->lr_save_p)));
20387 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20389 fprintf (file, "%d,",
20390 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20392 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20393 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20395 if (optional_tbtab)
20397 /* Compute the parameter info from the function decl argument
20400 int next_parm_info_bit = 31;
20402 for (decl = DECL_ARGUMENTS (current_function_decl);
20403 decl; decl = TREE_CHAIN (decl))
20405 rtx parameter = DECL_INCOMING_RTL (decl);
20406 enum machine_mode mode = GET_MODE (parameter);
20408 if (GET_CODE (parameter) == REG)
20410 if (SCALAR_FLOAT_MODE_P (mode))
20431 gcc_unreachable ();
20434 /* If only one bit will fit, don't or in this entry. */
20435 if (next_parm_info_bit > 0)
20436 parm_info |= (bits << (next_parm_info_bit - 1));
20437 next_parm_info_bit -= 2;
20441 fixed_parms += ((GET_MODE_SIZE (mode)
20442 + (UNITS_PER_WORD - 1))
20444 next_parm_info_bit -= 1;
20450 /* Number of fixed point parameters. */
20451 /* This is actually the number of words of fixed point parameters; thus
20452 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20453 fprintf (file, "%d,", fixed_parms);
20455 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20457 /* This is actually the number of fp registers that hold parameters;
20458 and thus the maximum value is 13. */
20459 /* Set parameters on stack bit if parameters are not in their original
20460 registers, regardless of whether they are on the stack? Xlc
20461 seems to set the bit when not optimizing. */
20462 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20464 if (! optional_tbtab)
20467 /* Optional fields follow. Some are variable length. */
20469 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20470 11 double float. */
20471 /* There is an entry for each parameter in a register, in the order that
20472 they occur in the parameter list. Any intervening arguments on the
20473 stack are ignored. If the list overflows a long (max possible length
20474 34 bits) then completely leave off all elements that don't fit. */
20475 /* Only emit this long if there was at least one parameter. */
20476 if (fixed_parms || float_parms)
20477 fprintf (file, "\t.long %d\n", parm_info);
20479 /* Offset from start of code to tb table. */
20480 fputs ("\t.long ", file);
20481 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20483 RS6000_OUTPUT_BASENAME (file, fname);
20485 assemble_name (file, fname);
20487 rs6000_output_function_entry (file, fname);
20490 /* Interrupt handler mask. */
20491 /* Omit this long, since we never set the interrupt handler bit
20494 /* Number of CTL (controlled storage) anchors. */
20495 /* Omit this long, since the has_ctl bit is never set above. */
20497 /* Displacement into stack of each CTL anchor. */
20498 /* Omit this list of longs, because there are no CTL anchors. */
20500 /* Length of function name. */
20503 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20505 /* Function name. */
20506 assemble_string (fname, strlen (fname));
20508 /* Register for alloca automatic storage; this is always reg 31.
20509 Only emit this if the alloca bit was set above. */
20510 if (frame_pointer_needed)
20511 fputs ("\t.byte 31\n", file);
20513 fputs ("\t.align 2\n", file);
20517 /* A C compound statement that outputs the assembler code for a thunk
20518 function, used to implement C++ virtual function calls with
20519 multiple inheritance. The thunk acts as a wrapper around a virtual
20520 function, adjusting the implicit object parameter before handing
20521 control off to the real function.
20523 First, emit code to add the integer DELTA to the location that
20524 contains the incoming first argument. Assume that this argument
20525 contains a pointer, and is the one used to pass the `this' pointer
20526 in C++. This is the incoming argument *before* the function
20527 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20528 values of all other incoming arguments.
20530 After the addition, emit code to jump to FUNCTION, which is a
20531 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20532 not touch the return address. Hence returning from FUNCTION will
20533 return to whoever called the current `thunk'.
20535 The effect must be as if FUNCTION had been called directly with the
20536 adjusted first argument. This macro is responsible for emitting
20537 all of the code for a thunk function; output_function_prologue()
20538 and output_function_epilogue() are not invoked.
20540 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20541 been extracted from it.) It might possibly be useful on some
20542 targets, but probably not.
20544 If you do not define this macro, the target-independent code in the
20545 C++ frontend will generate a less efficient heavyweight thunk that
20546 calls FUNCTION instead of jumping to it. The generic approach does
20547 not support varargs. */
20550 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20551 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20554 rtx this_rtx, insn, funexp;
20556 reload_completed = 1;
20557 epilogue_completed = 1;
20559 /* Mark the end of the (empty) prologue. */
20560 emit_note (NOTE_INSN_PROLOGUE_END);
20562 /* Find the "this" pointer. If the function returns a structure,
20563 the structure return pointer is in r3. */
20564 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20565 this_rtx = gen_rtx_REG (Pmode, 4);
20567 this_rtx = gen_rtx_REG (Pmode, 3);
20569 /* Apply the constant offset, if required. */
20571 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20573 /* Apply the offset from the vtable, if required. */
20576 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20577 rtx tmp = gen_rtx_REG (Pmode, 12);
20579 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20580 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20582 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20583 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20587 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20589 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20591 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20594 /* Generate a tail call to the target function. */
20595 if (!TREE_USED (function))
20597 assemble_external (function);
20598 TREE_USED (function) = 1;
20600 funexp = XEXP (DECL_RTL (function), 0);
20601 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20604 if (MACHOPIC_INDIRECT)
20605 funexp = machopic_indirect_call_target (funexp);
20608 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20609 generate sibcall RTL explicitly. */
20610 insn = emit_call_insn (
20611 gen_rtx_PARALLEL (VOIDmode,
20613 gen_rtx_CALL (VOIDmode,
20614 funexp, const0_rtx),
20615 gen_rtx_USE (VOIDmode, const0_rtx),
20616 gen_rtx_USE (VOIDmode,
20617 gen_rtx_REG (SImode,
20619 gen_rtx_RETURN (VOIDmode))));
20620 SIBLING_CALL_P (insn) = 1;
20623 /* Run just enough of rest_of_compilation to get the insns emitted.
20624 There's not really enough bulk here to make other passes such as
20625 instruction scheduling worth while. Note that use_thunk calls
20626 assemble_start_function and assemble_end_function. */
20627 insn = get_insns ();
20628 insn_locators_alloc ();
20629 shorten_branches (insn);
20630 final_start_function (insn, file, 1);
20631 final (insn, file, 1);
20632 final_end_function ();
20634 reload_completed = 0;
20635 epilogue_completed = 0;
20638 /* A quick summary of the various types of 'constant-pool tables'
20641 Target Flags Name One table per
20642 AIX (none) AIX TOC object file
20643 AIX -mfull-toc AIX TOC object file
20644 AIX -mminimal-toc AIX minimal TOC translation unit
20645 SVR4/EABI (none) SVR4 SDATA object file
20646 SVR4/EABI -fpic SVR4 pic object file
20647 SVR4/EABI -fPIC SVR4 PIC translation unit
20648 SVR4/EABI -mrelocatable EABI TOC function
20649 SVR4/EABI -maix AIX TOC object file
20650 SVR4/EABI -maix -mminimal-toc
20651 AIX minimal TOC translation unit
20653 Name Reg. Set by entries contains:
20654 made by addrs? fp? sum?
20656 AIX TOC 2 crt0 as Y option option
20657 AIX minimal TOC 30 prolog gcc Y Y option
20658 SVR4 SDATA 13 crt0 gcc N Y N
20659 SVR4 pic 30 prolog ld Y not yet N
20660 SVR4 PIC 30 prolog gcc Y option option
20661 EABI TOC 30 prolog gcc Y option option
20665 /* Hash functions for the hash table. */
20668 rs6000_hash_constant (rtx k)
20670 enum rtx_code code = GET_CODE (k);
20671 enum machine_mode mode = GET_MODE (k);
20672 unsigned result = (code << 3) ^ mode;
20673 const char *format;
20676 format = GET_RTX_FORMAT (code);
20677 flen = strlen (format);
20683 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20686 if (mode != VOIDmode)
20687 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20699 for (; fidx < flen; fidx++)
20700 switch (format[fidx])
20705 const char *str = XSTR (k, fidx);
20706 len = strlen (str);
20707 result = result * 613 + len;
20708 for (i = 0; i < len; i++)
20709 result = result * 613 + (unsigned) str[i];
20714 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20718 result = result * 613 + (unsigned) XINT (k, fidx);
20721 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20722 result = result * 613 + (unsigned) XWINT (k, fidx);
20726 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20727 result = result * 613 + (unsigned) (XWINT (k, fidx)
20734 gcc_unreachable ();
20741 toc_hash_function (const void *hash_entry)
20743 const struct toc_hash_struct *thc =
20744 (const struct toc_hash_struct *) hash_entry;
20745 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20748 /* Compare H1 and H2 for equivalence. */
20751 toc_hash_eq (const void *h1, const void *h2)
20753 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20754 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20756 if (((const struct toc_hash_struct *) h1)->key_mode
20757 != ((const struct toc_hash_struct *) h2)->key_mode)
20760 return rtx_equal_p (r1, r2);
20763 /* These are the names given by the C++ front-end to vtables, and
20764 vtable-like objects. Ideally, this logic should not be here;
20765 instead, there should be some programmatic way of inquiring as
20766 to whether or not an object is a vtable. */
20768 #define VTABLE_NAME_P(NAME) \
20769 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20770 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20771 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20772 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20773 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20775 #ifdef NO_DOLLAR_IN_LABEL
20776 /* Return a GGC-allocated character string translating dollar signs in
20777 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20780 rs6000_xcoff_strip_dollar (const char *name)
20785 p = strchr (name, '$');
20787 if (p == 0 || p == name)
20790 len = strlen (name);
20791 strip = (char *) alloca (len + 1);
20792 strcpy (strip, name);
20793 p = strchr (strip, '$');
20797 p = strchr (p + 1, '$');
20800 return ggc_alloc_string (strip, len);
20805 rs6000_output_symbol_ref (FILE *file, rtx x)
20807 /* Currently C++ toc references to vtables can be emitted before it
20808 is decided whether the vtable is public or private. If this is
20809 the case, then the linker will eventually complain that there is
20810 a reference to an unknown section. Thus, for vtables only,
20811 we emit the TOC reference to reference the symbol and not the
20813 const char *name = XSTR (x, 0);
20815 if (VTABLE_NAME_P (name))
20817 RS6000_OUTPUT_BASENAME (file, name);
20820 assemble_name (file, name);
20823 /* Output a TOC entry. We derive the entry name from what is being
20827 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20830 const char *name = buf;
20832 HOST_WIDE_INT offset = 0;
20834 gcc_assert (!TARGET_NO_TOC);
20836 /* When the linker won't eliminate them, don't output duplicate
20837 TOC entries (this happens on AIX if there is any kind of TOC,
20838 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20840 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20842 struct toc_hash_struct *h;
20845 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20846 time because GGC is not initialized at that point. */
20847 if (toc_hash_table == NULL)
20848 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20849 toc_hash_eq, NULL);
20851 h = GGC_NEW (struct toc_hash_struct);
20853 h->key_mode = mode;
20854 h->labelno = labelno;
20856 found = htab_find_slot (toc_hash_table, h, INSERT);
20857 if (*found == NULL)
20859 else /* This is indeed a duplicate.
20860 Set this label equal to that label. */
20862 fputs ("\t.set ", file);
20863 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20864 fprintf (file, "%d,", labelno);
20865 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20866 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20872 /* If we're going to put a double constant in the TOC, make sure it's
20873 aligned properly when strict alignment is on. */
20874 if (GET_CODE (x) == CONST_DOUBLE
20875 && STRICT_ALIGNMENT
20876 && GET_MODE_BITSIZE (mode) >= 64
20877 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20878 ASM_OUTPUT_ALIGN (file, 3);
20881 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20883 /* Handle FP constants specially. Note that if we have a minimal
20884 TOC, things we put here aren't actually in the TOC, so we can allow
20886 if (GET_CODE (x) == CONST_DOUBLE &&
20887 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20889 REAL_VALUE_TYPE rv;
20892 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20893 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20894 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20896 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20900 if (TARGET_MINIMAL_TOC)
20901 fputs (DOUBLE_INT_ASM_OP, file);
20903 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20904 k[0] & 0xffffffff, k[1] & 0xffffffff,
20905 k[2] & 0xffffffff, k[3] & 0xffffffff);
20906 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20907 k[0] & 0xffffffff, k[1] & 0xffffffff,
20908 k[2] & 0xffffffff, k[3] & 0xffffffff);
20913 if (TARGET_MINIMAL_TOC)
20914 fputs ("\t.long ", file);
20916 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20917 k[0] & 0xffffffff, k[1] & 0xffffffff,
20918 k[2] & 0xffffffff, k[3] & 0xffffffff);
20919 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20920 k[0] & 0xffffffff, k[1] & 0xffffffff,
20921 k[2] & 0xffffffff, k[3] & 0xffffffff);
20925 else if (GET_CODE (x) == CONST_DOUBLE &&
20926 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20928 REAL_VALUE_TYPE rv;
20931 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20933 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20934 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20936 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20940 if (TARGET_MINIMAL_TOC)
20941 fputs (DOUBLE_INT_ASM_OP, file);
20943 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20944 k[0] & 0xffffffff, k[1] & 0xffffffff);
20945 fprintf (file, "0x%lx%08lx\n",
20946 k[0] & 0xffffffff, k[1] & 0xffffffff);
20951 if (TARGET_MINIMAL_TOC)
20952 fputs ("\t.long ", file);
20954 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20955 k[0] & 0xffffffff, k[1] & 0xffffffff);
20956 fprintf (file, "0x%lx,0x%lx\n",
20957 k[0] & 0xffffffff, k[1] & 0xffffffff);
20961 else if (GET_CODE (x) == CONST_DOUBLE &&
20962 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20964 REAL_VALUE_TYPE rv;
20967 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20968 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20969 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20971 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20975 if (TARGET_MINIMAL_TOC)
20976 fputs (DOUBLE_INT_ASM_OP, file);
20978 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20979 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20984 if (TARGET_MINIMAL_TOC)
20985 fputs ("\t.long ", file);
20987 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20988 fprintf (file, "0x%lx\n", l & 0xffffffff);
20992 else if (GET_MODE (x) == VOIDmode
20993 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20995 unsigned HOST_WIDE_INT low;
20996 HOST_WIDE_INT high;
20998 if (GET_CODE (x) == CONST_DOUBLE)
21000 low = CONST_DOUBLE_LOW (x);
21001 high = CONST_DOUBLE_HIGH (x);
21004 #if HOST_BITS_PER_WIDE_INT == 32
21007 high = (low & 0x80000000) ? ~0 : 0;
21011 low = INTVAL (x) & 0xffffffff;
21012 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21016 /* TOC entries are always Pmode-sized, but since this
21017 is a bigendian machine then if we're putting smaller
21018 integer constants in the TOC we have to pad them.
21019 (This is still a win over putting the constants in
21020 a separate constant pool, because then we'd have
21021 to have both a TOC entry _and_ the actual constant.)
21023 For a 32-bit target, CONST_INT values are loaded and shifted
21024 entirely within `low' and can be stored in one TOC entry. */
21026 /* It would be easy to make this work, but it doesn't now. */
21027 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21029 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21031 #if HOST_BITS_PER_WIDE_INT == 32
21032 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21033 POINTER_SIZE, &low, &high, 0);
21036 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21037 high = (HOST_WIDE_INT) low >> 32;
21044 if (TARGET_MINIMAL_TOC)
21045 fputs (DOUBLE_INT_ASM_OP, file);
21047 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21048 (long) high & 0xffffffff, (long) low & 0xffffffff);
21049 fprintf (file, "0x%lx%08lx\n",
21050 (long) high & 0xffffffff, (long) low & 0xffffffff);
21055 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21057 if (TARGET_MINIMAL_TOC)
21058 fputs ("\t.long ", file);
21060 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21061 (long) high & 0xffffffff, (long) low & 0xffffffff);
21062 fprintf (file, "0x%lx,0x%lx\n",
21063 (long) high & 0xffffffff, (long) low & 0xffffffff);
21067 if (TARGET_MINIMAL_TOC)
21068 fputs ("\t.long ", file);
21070 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21071 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21077 if (GET_CODE (x) == CONST)
21079 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21080 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21082 base = XEXP (XEXP (x, 0), 0);
21083 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21086 switch (GET_CODE (base))
21089 name = XSTR (base, 0);
21093 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21094 CODE_LABEL_NUMBER (XEXP (base, 0)));
21098 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21102 gcc_unreachable ();
21105 if (TARGET_MINIMAL_TOC)
21106 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21109 fputs ("\t.tc ", file);
21110 RS6000_OUTPUT_BASENAME (file, name);
21113 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21115 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21117 fputs ("[TC],", file);
21120 /* Currently C++ toc references to vtables can be emitted before it
21121 is decided whether the vtable is public or private. If this is
21122 the case, then the linker will eventually complain that there is
21123 a TOC reference to an unknown section. Thus, for vtables only,
21124 we emit the TOC reference to reference the symbol and not the
21126 if (VTABLE_NAME_P (name))
21128 RS6000_OUTPUT_BASENAME (file, name);
21130 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21131 else if (offset > 0)
21132 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21135 output_addr_const (file, x);
21139 /* Output an assembler pseudo-op to write an ASCII string of N characters
21140 starting at P to FILE.
21142 On the RS/6000, we have to do this using the .byte operation and
21143 write out special characters outside the quoted string.
21144 Also, the assembler is broken; very long strings are truncated,
21145 so we must artificially break them up early. */
21148 output_ascii (FILE *file, const char *p, int n)
21151 int i, count_string;
21152 const char *for_string = "\t.byte \"";
21153 const char *for_decimal = "\t.byte ";
21154 const char *to_close = NULL;
21157 for (i = 0; i < n; i++)
21160 if (c >= ' ' && c < 0177)
21163 fputs (for_string, file);
21166 /* Write two quotes to get one. */
21174 for_decimal = "\"\n\t.byte ";
21178 if (count_string >= 512)
21180 fputs (to_close, file);
21182 for_string = "\t.byte \"";
21183 for_decimal = "\t.byte ";
21191 fputs (for_decimal, file);
21192 fprintf (file, "%d", c);
21194 for_string = "\n\t.byte \"";
21195 for_decimal = ", ";
21201 /* Now close the string if we have written one. Then end the line. */
21203 fputs (to_close, file);
21206 /* Generate a unique section name for FILENAME for a section type
21207 represented by SECTION_DESC. Output goes into BUF.
21209 SECTION_DESC can be any string, as long as it is different for each
21210 possible section type.
21212 We name the section in the same manner as xlc. The name begins with an
21213 underscore followed by the filename (after stripping any leading directory
21214 names) with the last period replaced by the string SECTION_DESC. If
21215 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21219 rs6000_gen_section_name (char **buf, const char *filename,
21220 const char *section_desc)
21222 const char *q, *after_last_slash, *last_period = 0;
21226 after_last_slash = filename;
21227 for (q = filename; *q; q++)
21230 after_last_slash = q + 1;
21231 else if (*q == '.')
21235 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21236 *buf = (char *) xmalloc (len);
21241 for (q = after_last_slash; *q; q++)
21243 if (q == last_period)
21245 strcpy (p, section_desc);
21246 p += strlen (section_desc);
21250 else if (ISALNUM (*q))
21254 if (last_period == 0)
21255 strcpy (p, section_desc);
21260 /* Emit profile function. */
21263 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21265 /* Non-standard profiling for kernels, which just saves LR then calls
21266 _mcount without worrying about arg saves. The idea is to change
21267 the function prologue as little as possible as it isn't easy to
21268 account for arg save/restore code added just for _mcount. */
21269 if (TARGET_PROFILE_KERNEL)
21272 if (DEFAULT_ABI == ABI_AIX)
21274 #ifndef NO_PROFILE_COUNTERS
21275 # define NO_PROFILE_COUNTERS 0
21277 if (NO_PROFILE_COUNTERS)
21278 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21279 LCT_NORMAL, VOIDmode, 0);
21283 const char *label_name;
21286 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21287 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21288 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21290 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21291 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21294 else if (DEFAULT_ABI == ABI_DARWIN)
21296 const char *mcount_name = RS6000_MCOUNT;
21297 int caller_addr_regno = LR_REGNO;
21299 /* Be conservative and always set this, at least for now. */
21300 crtl->uses_pic_offset_table = 1;
21303 /* For PIC code, set up a stub and collect the caller's address
21304 from r0, which is where the prologue puts it. */
21305 if (MACHOPIC_INDIRECT
21306 && crtl->uses_pic_offset_table)
21307 caller_addr_regno = 0;
21309 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21310 LCT_NORMAL, VOIDmode, 1,
21311 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21315 /* Write function profiler code. */
21318 output_function_profiler (FILE *file, int labelno)
21322 switch (DEFAULT_ABI)
21325 gcc_unreachable ();
21330 warning (0, "no profiling of 64-bit code for this ABI");
21333 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21334 fprintf (file, "\tmflr %s\n", reg_names[0]);
21335 if (NO_PROFILE_COUNTERS)
21337 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21338 reg_names[0], reg_names[1]);
21340 else if (TARGET_SECURE_PLT && flag_pic)
21342 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21343 reg_names[0], reg_names[1]);
21344 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21345 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21346 reg_names[12], reg_names[12]);
21347 assemble_name (file, buf);
21348 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21349 assemble_name (file, buf);
21350 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21352 else if (flag_pic == 1)
21354 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21355 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21356 reg_names[0], reg_names[1]);
21357 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21358 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21359 assemble_name (file, buf);
21360 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21362 else if (flag_pic > 1)
21364 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21365 reg_names[0], reg_names[1]);
21366 /* Now, we need to get the address of the label. */
21367 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21368 assemble_name (file, buf);
21369 fputs ("-.\n1:", file);
21370 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21371 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21372 reg_names[0], reg_names[11]);
21373 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21374 reg_names[0], reg_names[0], reg_names[11]);
21378 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21379 assemble_name (file, buf);
21380 fputs ("@ha\n", file);
21381 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21382 reg_names[0], reg_names[1]);
21383 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21384 assemble_name (file, buf);
21385 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21388 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21389 fprintf (file, "\tbl %s%s\n",
21390 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21395 if (!TARGET_PROFILE_KERNEL)
21397 /* Don't do anything, done in output_profile_hook (). */
21401 gcc_assert (!TARGET_32BIT);
21403 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21404 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21406 if (cfun->static_chain_decl != NULL)
21408 asm_fprintf (file, "\tstd %s,24(%s)\n",
21409 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21410 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21411 asm_fprintf (file, "\tld %s,24(%s)\n",
21412 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21415 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21423 /* The following variable value is the last issued insn. */
21425 static rtx last_scheduled_insn;
21427 /* The following variable helps to balance issuing of load and
21428 store instructions */
21430 static int load_store_pendulum;
21432 /* Power4 load update and store update instructions are cracked into a
21433 load or store and an integer insn which are executed in the same cycle.
21434 Branches have their own dispatch slot which does not count against the
21435 GCC issue rate, but it changes the program flow so there are no other
21436 instructions to issue in this cycle. */
21439 rs6000_variable_issue_1 (rtx insn, int more)
21441 last_scheduled_insn = insn;
21442 if (GET_CODE (PATTERN (insn)) == USE
21443 || GET_CODE (PATTERN (insn)) == CLOBBER)
21445 cached_can_issue_more = more;
21446 return cached_can_issue_more;
21449 if (insn_terminates_group_p (insn, current_group))
21451 cached_can_issue_more = 0;
21452 return cached_can_issue_more;
21455 /* If no reservation, but reach here */
21456 if (recog_memoized (insn) < 0)
21459 if (rs6000_sched_groups)
21461 if (is_microcoded_insn (insn))
21462 cached_can_issue_more = 0;
21463 else if (is_cracked_insn (insn))
21464 cached_can_issue_more = more > 2 ? more - 2 : 0;
21466 cached_can_issue_more = more - 1;
21468 return cached_can_issue_more;
21471 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21474 cached_can_issue_more = more - 1;
21475 return cached_can_issue_more;
21479 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21481 int r = rs6000_variable_issue_1 (insn, more);
21483 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21487 /* Adjust the cost of a scheduling dependency. Return the new cost of
21488 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21491 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21493 enum attr_type attr_type;
21495 if (! recog_memoized (insn))
21498 switch (REG_NOTE_KIND (link))
21502 /* Data dependency; DEP_INSN writes a register that INSN reads
21503 some cycles later. */
21505 /* Separate a load from a narrower, dependent store. */
21506 if (rs6000_sched_groups
21507 && GET_CODE (PATTERN (insn)) == SET
21508 && GET_CODE (PATTERN (dep_insn)) == SET
21509 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21510 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21511 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21512 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21515 attr_type = get_attr_type (insn);
21520 /* Tell the first scheduling pass about the latency between
21521 a mtctr and bctr (and mtlr and br/blr). The first
21522 scheduling pass will not know about this latency since
21523 the mtctr instruction, which has the latency associated
21524 to it, will be generated by reload. */
21525 return TARGET_POWER ? 5 : 4;
21527 /* Leave some extra cycles between a compare and its
21528 dependent branch, to inhibit expensive mispredicts. */
21529 if ((rs6000_cpu_attr == CPU_PPC603
21530 || rs6000_cpu_attr == CPU_PPC604
21531 || rs6000_cpu_attr == CPU_PPC604E
21532 || rs6000_cpu_attr == CPU_PPC620
21533 || rs6000_cpu_attr == CPU_PPC630
21534 || rs6000_cpu_attr == CPU_PPC750
21535 || rs6000_cpu_attr == CPU_PPC7400
21536 || rs6000_cpu_attr == CPU_PPC7450
21537 || rs6000_cpu_attr == CPU_POWER4
21538 || rs6000_cpu_attr == CPU_POWER5
21539 || rs6000_cpu_attr == CPU_POWER7
21540 || rs6000_cpu_attr == CPU_CELL)
21541 && recog_memoized (dep_insn)
21542 && (INSN_CODE (dep_insn) >= 0))
21544 switch (get_attr_type (dep_insn))
21548 case TYPE_DELAYED_COMPARE:
21549 case TYPE_IMUL_COMPARE:
21550 case TYPE_LMUL_COMPARE:
21551 case TYPE_FPCOMPARE:
21552 case TYPE_CR_LOGICAL:
21553 case TYPE_DELAYED_CR:
21562 case TYPE_STORE_UX:
21564 case TYPE_FPSTORE_U:
21565 case TYPE_FPSTORE_UX:
21566 if ((rs6000_cpu == PROCESSOR_POWER6)
21567 && recog_memoized (dep_insn)
21568 && (INSN_CODE (dep_insn) >= 0))
21571 if (GET_CODE (PATTERN (insn)) != SET)
21572 /* If this happens, we have to extend this to schedule
21573 optimally. Return default for now. */
21576 /* Adjust the cost for the case where the value written
21577 by a fixed point operation is used as the address
21578 gen value on a store. */
21579 switch (get_attr_type (dep_insn))
21586 if (! store_data_bypass_p (dep_insn, insn))
21590 case TYPE_LOAD_EXT:
21591 case TYPE_LOAD_EXT_U:
21592 case TYPE_LOAD_EXT_UX:
21593 case TYPE_VAR_SHIFT_ROTATE:
21594 case TYPE_VAR_DELAYED_COMPARE:
21596 if (! store_data_bypass_p (dep_insn, insn))
21602 case TYPE_FAST_COMPARE:
21605 case TYPE_INSERT_WORD:
21606 case TYPE_INSERT_DWORD:
21607 case TYPE_FPLOAD_U:
21608 case TYPE_FPLOAD_UX:
21610 case TYPE_STORE_UX:
21611 case TYPE_FPSTORE_U:
21612 case TYPE_FPSTORE_UX:
21614 if (! store_data_bypass_p (dep_insn, insn))
21622 case TYPE_IMUL_COMPARE:
21623 case TYPE_LMUL_COMPARE:
21625 if (! store_data_bypass_p (dep_insn, insn))
21631 if (! store_data_bypass_p (dep_insn, insn))
21637 if (! store_data_bypass_p (dep_insn, insn))
21650 case TYPE_LOAD_EXT:
21651 case TYPE_LOAD_EXT_U:
21652 case TYPE_LOAD_EXT_UX:
21653 if ((rs6000_cpu == PROCESSOR_POWER6)
21654 && recog_memoized (dep_insn)
21655 && (INSN_CODE (dep_insn) >= 0))
21658 /* Adjust the cost for the case where the value written
21659 by a fixed point instruction is used within the address
21660 gen portion of a subsequent load(u)(x) */
21661 switch (get_attr_type (dep_insn))
21668 if (set_to_load_agen (dep_insn, insn))
21672 case TYPE_LOAD_EXT:
21673 case TYPE_LOAD_EXT_U:
21674 case TYPE_LOAD_EXT_UX:
21675 case TYPE_VAR_SHIFT_ROTATE:
21676 case TYPE_VAR_DELAYED_COMPARE:
21678 if (set_to_load_agen (dep_insn, insn))
21684 case TYPE_FAST_COMPARE:
21687 case TYPE_INSERT_WORD:
21688 case TYPE_INSERT_DWORD:
21689 case TYPE_FPLOAD_U:
21690 case TYPE_FPLOAD_UX:
21692 case TYPE_STORE_UX:
21693 case TYPE_FPSTORE_U:
21694 case TYPE_FPSTORE_UX:
21696 if (set_to_load_agen (dep_insn, insn))
21704 case TYPE_IMUL_COMPARE:
21705 case TYPE_LMUL_COMPARE:
21707 if (set_to_load_agen (dep_insn, insn))
21713 if (set_to_load_agen (dep_insn, insn))
21719 if (set_to_load_agen (dep_insn, insn))
21730 if ((rs6000_cpu == PROCESSOR_POWER6)
21731 && recog_memoized (dep_insn)
21732 && (INSN_CODE (dep_insn) >= 0)
21733 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21740 /* Fall out to return default cost. */
21744 case REG_DEP_OUTPUT:
21745 /* Output dependency; DEP_INSN writes a register that INSN writes some
21747 if ((rs6000_cpu == PROCESSOR_POWER6)
21748 && recog_memoized (dep_insn)
21749 && (INSN_CODE (dep_insn) >= 0))
21751 attr_type = get_attr_type (insn);
21756 if (get_attr_type (dep_insn) == TYPE_FP)
21760 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21768 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21773 gcc_unreachable ();
21779 /* Debug version of rs6000_adjust_cost. */
21782 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21784 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21790 switch (REG_NOTE_KIND (link))
21792 default: dep = "unknown depencency"; break;
21793 case REG_DEP_TRUE: dep = "data dependency"; break;
21794 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21795 case REG_DEP_ANTI: dep = "anti depencency"; break;
21799 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21800 "%s, insn:\n", ret, cost, dep);
21808 /* The function returns a true if INSN is microcoded.
21809 Return false otherwise. */
21812 is_microcoded_insn (rtx insn)
21814 if (!insn || !NONDEBUG_INSN_P (insn)
21815 || GET_CODE (PATTERN (insn)) == USE
21816 || GET_CODE (PATTERN (insn)) == CLOBBER)
21819 if (rs6000_cpu_attr == CPU_CELL)
21820 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21822 if (rs6000_sched_groups)
21824 enum attr_type type = get_attr_type (insn);
21825 if (type == TYPE_LOAD_EXT_U
21826 || type == TYPE_LOAD_EXT_UX
21827 || type == TYPE_LOAD_UX
21828 || type == TYPE_STORE_UX
21829 || type == TYPE_MFCR)
21836 /* The function returns true if INSN is cracked into 2 instructions
21837 by the processor (and therefore occupies 2 issue slots). */
21840 is_cracked_insn (rtx insn)
21842 if (!insn || !NONDEBUG_INSN_P (insn)
21843 || GET_CODE (PATTERN (insn)) == USE
21844 || GET_CODE (PATTERN (insn)) == CLOBBER)
21847 if (rs6000_sched_groups)
21849 enum attr_type type = get_attr_type (insn);
21850 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21851 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21852 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21853 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21854 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21855 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21856 || type == TYPE_IDIV || type == TYPE_LDIV
21857 || type == TYPE_INSERT_WORD)
21864 /* The function returns true if INSN can be issued only from
21865 the branch slot. */
21868 is_branch_slot_insn (rtx insn)
21870 if (!insn || !NONDEBUG_INSN_P (insn)
21871 || GET_CODE (PATTERN (insn)) == USE
21872 || GET_CODE (PATTERN (insn)) == CLOBBER)
21875 if (rs6000_sched_groups)
21877 enum attr_type type = get_attr_type (insn);
21878 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21886 /* The function returns true if out_inst sets a value that is
21887 used in the address generation computation of in_insn */
21889 set_to_load_agen (rtx out_insn, rtx in_insn)
21891 rtx out_set, in_set;
21893 /* For performance reasons, only handle the simple case where
21894 both loads are a single_set. */
21895 out_set = single_set (out_insn);
21898 in_set = single_set (in_insn);
21900 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21906 /* The function returns true if the target storage location of
21907 out_insn is adjacent to the target storage location of in_insn */
21908 /* Return 1 if memory locations are adjacent. */
21911 adjacent_mem_locations (rtx insn1, rtx insn2)
21914 rtx a = get_store_dest (PATTERN (insn1));
21915 rtx b = get_store_dest (PATTERN (insn2));
21917 if ((GET_CODE (XEXP (a, 0)) == REG
21918 || (GET_CODE (XEXP (a, 0)) == PLUS
21919 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21920 && (GET_CODE (XEXP (b, 0)) == REG
21921 || (GET_CODE (XEXP (b, 0)) == PLUS
21922 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21924 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21927 if (GET_CODE (XEXP (a, 0)) == PLUS)
21929 reg0 = XEXP (XEXP (a, 0), 0);
21930 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21933 reg0 = XEXP (a, 0);
21935 if (GET_CODE (XEXP (b, 0)) == PLUS)
21937 reg1 = XEXP (XEXP (b, 0), 0);
21938 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21941 reg1 = XEXP (b, 0);
21943 val_diff = val1 - val0;
21945 return ((REGNO (reg0) == REGNO (reg1))
21946 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21947 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21953 /* A C statement (sans semicolon) to update the integer scheduling
21954 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21955 INSN earlier, reduce the priority to execute INSN later. Do not
21956 define this macro if you do not need to adjust the scheduling
21957 priorities of insns. */
21960 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21962 /* On machines (like the 750) which have asymmetric integer units,
21963 where one integer unit can do multiply and divides and the other
21964 can't, reduce the priority of multiply/divide so it is scheduled
21965 before other integer operations. */
21968 if (! INSN_P (insn))
21971 if (GET_CODE (PATTERN (insn)) == USE)
21974 switch (rs6000_cpu_attr) {
21976 switch (get_attr_type (insn))
21983 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21984 priority, priority);
21985 if (priority >= 0 && priority < 0x01000000)
21992 if (insn_must_be_first_in_group (insn)
21993 && reload_completed
21994 && current_sched_info->sched_max_insns_priority
21995 && rs6000_sched_restricted_insns_priority)
21998 /* Prioritize insns that can be dispatched only in the first
22000 if (rs6000_sched_restricted_insns_priority == 1)
22001 /* Attach highest priority to insn. This means that in
22002 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22003 precede 'priority' (critical path) considerations. */
22004 return current_sched_info->sched_max_insns_priority;
22005 else if (rs6000_sched_restricted_insns_priority == 2)
22006 /* Increase priority of insn by a minimal amount. This means that in
22007 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22008 considerations precede dispatch-slot restriction considerations. */
22009 return (priority + 1);
22012 if (rs6000_cpu == PROCESSOR_POWER6
22013 && ((load_store_pendulum == -2 && is_load_insn (insn))
22014 || (load_store_pendulum == 2 && is_store_insn (insn))))
22015 /* Attach highest priority to insn if the scheduler has just issued two
22016 stores and this instruction is a load, or two loads and this instruction
22017 is a store. Power6 wants loads and stores scheduled alternately
22019 return current_sched_info->sched_max_insns_priority;
22024 /* Return true if the instruction is nonpipelined on the Cell. */
22026 is_nonpipeline_insn (rtx insn)
22028 enum attr_type type;
22029 if (!insn || !NONDEBUG_INSN_P (insn)
22030 || GET_CODE (PATTERN (insn)) == USE
22031 || GET_CODE (PATTERN (insn)) == CLOBBER)
22034 type = get_attr_type (insn);
22035 if (type == TYPE_IMUL
22036 || type == TYPE_IMUL2
22037 || type == TYPE_IMUL3
22038 || type == TYPE_LMUL
22039 || type == TYPE_IDIV
22040 || type == TYPE_LDIV
22041 || type == TYPE_SDIV
22042 || type == TYPE_DDIV
22043 || type == TYPE_SSQRT
22044 || type == TYPE_DSQRT
22045 || type == TYPE_MFCR
22046 || type == TYPE_MFCRF
22047 || type == TYPE_MFJMPR)
22055 /* Return how many instructions the machine can issue per cycle. */
22058 rs6000_issue_rate (void)
22060 /* Unless scheduling for register pressure, use issue rate of 1 for
22061 first scheduling pass to decrease degradation. */
22062 if (!reload_completed && !flag_sched_pressure)
22065 switch (rs6000_cpu_attr) {
22066 case CPU_RIOS1: /* ? */
22068 case CPU_PPC601: /* ? */
22077 case CPU_PPCE300C2:
22078 case CPU_PPCE300C3:
22079 case CPU_PPCE500MC:
22080 case CPU_PPCE500MC64:
22099 /* Return how many instructions to look ahead for better insn
22103 rs6000_use_sched_lookahead (void)
22105 if (rs6000_cpu_attr == CPU_PPC8540)
22107 if (rs6000_cpu_attr == CPU_CELL)
22108 return (reload_completed ? 8 : 0);
22112 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22114 rs6000_use_sched_lookahead_guard (rtx insn)
22116 if (rs6000_cpu_attr != CPU_CELL)
22119 if (insn == NULL_RTX || !INSN_P (insn))
22122 if (!reload_completed
22123 || is_nonpipeline_insn (insn)
22124 || is_microcoded_insn (insn))
22130 /* Determine is PAT refers to memory. */
22133 is_mem_ref (rtx pat)
22139 /* stack_tie does not produce any real memory traffic. */
22140 if (GET_CODE (pat) == UNSPEC
22141 && XINT (pat, 1) == UNSPEC_TIE)
22144 if (GET_CODE (pat) == MEM)
22147 /* Recursively process the pattern. */
22148 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22150 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22153 ret |= is_mem_ref (XEXP (pat, i));
22154 else if (fmt[i] == 'E')
22155 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22156 ret |= is_mem_ref (XVECEXP (pat, i, j));
22162 /* Determine if PAT is a PATTERN of a load insn. */
22165 is_load_insn1 (rtx pat)
22167 if (!pat || pat == NULL_RTX)
22170 if (GET_CODE (pat) == SET)
22171 return is_mem_ref (SET_SRC (pat));
22173 if (GET_CODE (pat) == PARALLEL)
22177 for (i = 0; i < XVECLEN (pat, 0); i++)
22178 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22185 /* Determine if INSN loads from memory. */
22188 is_load_insn (rtx insn)
22190 if (!insn || !INSN_P (insn))
22193 if (GET_CODE (insn) == CALL_INSN)
22196 return is_load_insn1 (PATTERN (insn));
22199 /* Determine if PAT is a PATTERN of a store insn. */
22202 is_store_insn1 (rtx pat)
22204 if (!pat || pat == NULL_RTX)
22207 if (GET_CODE (pat) == SET)
22208 return is_mem_ref (SET_DEST (pat));
22210 if (GET_CODE (pat) == PARALLEL)
22214 for (i = 0; i < XVECLEN (pat, 0); i++)
22215 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22222 /* Determine if INSN stores to memory. */
22225 is_store_insn (rtx insn)
22227 if (!insn || !INSN_P (insn))
22230 return is_store_insn1 (PATTERN (insn));
22233 /* Return the dest of a store insn. */
22236 get_store_dest (rtx pat)
22238 gcc_assert (is_store_insn1 (pat));
22240 if (GET_CODE (pat) == SET)
22241 return SET_DEST (pat);
22242 else if (GET_CODE (pat) == PARALLEL)
22246 for (i = 0; i < XVECLEN (pat, 0); i++)
22248 rtx inner_pat = XVECEXP (pat, 0, i);
22249 if (GET_CODE (inner_pat) == SET
22250 && is_mem_ref (SET_DEST (inner_pat)))
22254 /* We shouldn't get here, because we should have either a simple
22255 store insn or a store with update which are covered above. */
22259 /* Returns whether the dependence between INSN and NEXT is considered
22260 costly by the given target. */
22263 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22268 /* If the flag is not enabled - no dependence is considered costly;
22269 allow all dependent insns in the same group.
22270 This is the most aggressive option. */
22271 if (rs6000_sched_costly_dep == no_dep_costly)
22274 /* If the flag is set to 1 - a dependence is always considered costly;
22275 do not allow dependent instructions in the same group.
22276 This is the most conservative option. */
22277 if (rs6000_sched_costly_dep == all_deps_costly)
22280 insn = DEP_PRO (dep);
22281 next = DEP_CON (dep);
22283 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22284 && is_load_insn (next)
22285 && is_store_insn (insn))
22286 /* Prevent load after store in the same group. */
22289 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22290 && is_load_insn (next)
22291 && is_store_insn (insn)
22292 && DEP_TYPE (dep) == REG_DEP_TRUE)
22293 /* Prevent load after store in the same group if it is a true
22297 /* The flag is set to X; dependences with latency >= X are considered costly,
22298 and will not be scheduled in the same group. */
22299 if (rs6000_sched_costly_dep <= max_dep_latency
22300 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22306 /* Return the next insn after INSN that is found before TAIL is reached,
22307 skipping any "non-active" insns - insns that will not actually occupy
22308 an issue slot. Return NULL_RTX if such an insn is not found. */
22311 get_next_active_insn (rtx insn, rtx tail)
22313 if (insn == NULL_RTX || insn == tail)
22318 insn = NEXT_INSN (insn);
22319 if (insn == NULL_RTX || insn == tail)
22324 || (NONJUMP_INSN_P (insn)
22325 && GET_CODE (PATTERN (insn)) != USE
22326 && GET_CODE (PATTERN (insn)) != CLOBBER
22327 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22333 /* We are about to begin issuing insns for this clock cycle. */
22336 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22337 rtx *ready ATTRIBUTE_UNUSED,
22338 int *pn_ready ATTRIBUTE_UNUSED,
22339 int clock_var ATTRIBUTE_UNUSED)
22341 int n_ready = *pn_ready;
22344 fprintf (dump, "// rs6000_sched_reorder :\n");
22346 /* Reorder the ready list, if the second to last ready insn
22347 is a nonepipeline insn. */
22348 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22350 if (is_nonpipeline_insn (ready[n_ready - 1])
22351 && (recog_memoized (ready[n_ready - 2]) > 0))
22352 /* Simply swap first two insns. */
22354 rtx tmp = ready[n_ready - 1];
22355 ready[n_ready - 1] = ready[n_ready - 2];
22356 ready[n_ready - 2] = tmp;
22360 if (rs6000_cpu == PROCESSOR_POWER6)
22361 load_store_pendulum = 0;
22363 return rs6000_issue_rate ();
22366 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22369 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22370 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22373 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22375 /* For Power6, we need to handle some special cases to try and keep the
22376 store queue from overflowing and triggering expensive flushes.
22378 This code monitors how load and store instructions are being issued
22379 and skews the ready list one way or the other to increase the likelihood
22380 that a desired instruction is issued at the proper time.
22382 A couple of things are done. First, we maintain a "load_store_pendulum"
22383 to track the current state of load/store issue.
22385 - If the pendulum is at zero, then no loads or stores have been
22386 issued in the current cycle so we do nothing.
22388 - If the pendulum is 1, then a single load has been issued in this
22389 cycle and we attempt to locate another load in the ready list to
22392 - If the pendulum is -2, then two stores have already been
22393 issued in this cycle, so we increase the priority of the first load
22394 in the ready list to increase it's likelihood of being chosen first
22397 - If the pendulum is -1, then a single store has been issued in this
22398 cycle and we attempt to locate another store in the ready list to
22399 issue with it, preferring a store to an adjacent memory location to
22400 facilitate store pairing in the store queue.
22402 - If the pendulum is 2, then two loads have already been
22403 issued in this cycle, so we increase the priority of the first store
22404 in the ready list to increase it's likelihood of being chosen first
22407 - If the pendulum < -2 or > 2, then do nothing.
22409 Note: This code covers the most common scenarios. There exist non
22410 load/store instructions which make use of the LSU and which
22411 would need to be accounted for to strictly model the behavior
22412 of the machine. Those instructions are currently unaccounted
22413 for to help minimize compile time overhead of this code.
22415 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22421 if (is_store_insn (last_scheduled_insn))
22422 /* Issuing a store, swing the load_store_pendulum to the left */
22423 load_store_pendulum--;
22424 else if (is_load_insn (last_scheduled_insn))
22425 /* Issuing a load, swing the load_store_pendulum to the right */
22426 load_store_pendulum++;
22428 return cached_can_issue_more;
22430 /* If the pendulum is balanced, or there is only one instruction on
22431 the ready list, then all is well, so return. */
22432 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22433 return cached_can_issue_more;
22435 if (load_store_pendulum == 1)
22437 /* A load has been issued in this cycle. Scan the ready list
22438 for another load to issue with it */
22443 if (is_load_insn (ready[pos]))
22445 /* Found a load. Move it to the head of the ready list,
22446 and adjust it's priority so that it is more likely to
22449 for (i=pos; i<*pn_ready-1; i++)
22450 ready[i] = ready[i + 1];
22451 ready[*pn_ready-1] = tmp;
22453 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22454 INSN_PRIORITY (tmp)++;
22460 else if (load_store_pendulum == -2)
22462 /* Two stores have been issued in this cycle. Increase the
22463 priority of the first load in the ready list to favor it for
22464 issuing in the next cycle. */
22469 if (is_load_insn (ready[pos])
22471 && INSN_PRIORITY_KNOWN (ready[pos]))
22473 INSN_PRIORITY (ready[pos])++;
22475 /* Adjust the pendulum to account for the fact that a load
22476 was found and increased in priority. This is to prevent
22477 increasing the priority of multiple loads */
22478 load_store_pendulum--;
22485 else if (load_store_pendulum == -1)
22487 /* A store has been issued in this cycle. Scan the ready list for
22488 another store to issue with it, preferring a store to an adjacent
22490 int first_store_pos = -1;
22496 if (is_store_insn (ready[pos]))
22498 /* Maintain the index of the first store found on the
22500 if (first_store_pos == -1)
22501 first_store_pos = pos;
22503 if (is_store_insn (last_scheduled_insn)
22504 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22506 /* Found an adjacent store. Move it to the head of the
22507 ready list, and adjust it's priority so that it is
22508 more likely to stay there */
22510 for (i=pos; i<*pn_ready-1; i++)
22511 ready[i] = ready[i + 1];
22512 ready[*pn_ready-1] = tmp;
22514 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22515 INSN_PRIORITY (tmp)++;
22517 first_store_pos = -1;
22525 if (first_store_pos >= 0)
22527 /* An adjacent store wasn't found, but a non-adjacent store was,
22528 so move the non-adjacent store to the front of the ready
22529 list, and adjust its priority so that it is more likely to
22531 tmp = ready[first_store_pos];
22532 for (i=first_store_pos; i<*pn_ready-1; i++)
22533 ready[i] = ready[i + 1];
22534 ready[*pn_ready-1] = tmp;
22535 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22536 INSN_PRIORITY (tmp)++;
22539 else if (load_store_pendulum == 2)
22541 /* Two loads have been issued in this cycle. Increase the priority
22542 of the first store in the ready list to favor it for issuing in
22548 if (is_store_insn (ready[pos])
22550 && INSN_PRIORITY_KNOWN (ready[pos]))
22552 INSN_PRIORITY (ready[pos])++;
22554 /* Adjust the pendulum to account for the fact that a store
22555 was found and increased in priority. This is to prevent
22556 increasing the priority of multiple stores */
22557 load_store_pendulum++;
22566 return cached_can_issue_more;
22569 /* Return whether the presence of INSN causes a dispatch group termination
22570 of group WHICH_GROUP.
22572 If WHICH_GROUP == current_group, this function will return true if INSN
22573 causes the termination of the current group (i.e, the dispatch group to
22574 which INSN belongs). This means that INSN will be the last insn in the
22575 group it belongs to.
22577 If WHICH_GROUP == previous_group, this function will return true if INSN
22578 causes the termination of the previous group (i.e, the dispatch group that
22579 precedes the group to which INSN belongs). This means that INSN will be
22580 the first insn in the group it belongs to). */
22583 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22590 first = insn_must_be_first_in_group (insn);
22591 last = insn_must_be_last_in_group (insn);
22596 if (which_group == current_group)
22598 else if (which_group == previous_group)
22606 insn_must_be_first_in_group (rtx insn)
22608 enum attr_type type;
22611 || GET_CODE (insn) == NOTE
22612 || DEBUG_INSN_P (insn)
22613 || GET_CODE (PATTERN (insn)) == USE
22614 || GET_CODE (PATTERN (insn)) == CLOBBER)
22617 switch (rs6000_cpu)
22619 case PROCESSOR_POWER5:
22620 if (is_cracked_insn (insn))
22622 case PROCESSOR_POWER4:
22623 if (is_microcoded_insn (insn))
22626 if (!rs6000_sched_groups)
22629 type = get_attr_type (insn);
22636 case TYPE_DELAYED_CR:
22637 case TYPE_CR_LOGICAL:
22651 case PROCESSOR_POWER6:
22652 type = get_attr_type (insn);
22656 case TYPE_INSERT_DWORD:
22660 case TYPE_VAR_SHIFT_ROTATE:
22667 case TYPE_INSERT_WORD:
22668 case TYPE_DELAYED_COMPARE:
22669 case TYPE_IMUL_COMPARE:
22670 case TYPE_LMUL_COMPARE:
22671 case TYPE_FPCOMPARE:
22682 case TYPE_LOAD_EXT_UX:
22684 case TYPE_STORE_UX:
22685 case TYPE_FPLOAD_U:
22686 case TYPE_FPLOAD_UX:
22687 case TYPE_FPSTORE_U:
22688 case TYPE_FPSTORE_UX:
22694 case PROCESSOR_POWER7:
22695 type = get_attr_type (insn);
22699 case TYPE_CR_LOGICAL:
22706 case TYPE_DELAYED_COMPARE:
22707 case TYPE_VAR_DELAYED_COMPARE:
22713 case TYPE_LOAD_EXT:
22714 case TYPE_LOAD_EXT_U:
22715 case TYPE_LOAD_EXT_UX:
22717 case TYPE_STORE_UX:
22718 case TYPE_FPLOAD_U:
22719 case TYPE_FPLOAD_UX:
22720 case TYPE_FPSTORE_U:
22721 case TYPE_FPSTORE_UX:
22737 insn_must_be_last_in_group (rtx insn)
22739 enum attr_type type;
22742 || GET_CODE (insn) == NOTE
22743 || DEBUG_INSN_P (insn)
22744 || GET_CODE (PATTERN (insn)) == USE
22745 || GET_CODE (PATTERN (insn)) == CLOBBER)
22748 switch (rs6000_cpu) {
22749 case PROCESSOR_POWER4:
22750 case PROCESSOR_POWER5:
22751 if (is_microcoded_insn (insn))
22754 if (is_branch_slot_insn (insn))
22758 case PROCESSOR_POWER6:
22759 type = get_attr_type (insn);
22766 case TYPE_VAR_SHIFT_ROTATE:
22773 case TYPE_DELAYED_COMPARE:
22774 case TYPE_IMUL_COMPARE:
22775 case TYPE_LMUL_COMPARE:
22776 case TYPE_FPCOMPARE:
22790 case PROCESSOR_POWER7:
22791 type = get_attr_type (insn);
22799 case TYPE_LOAD_EXT_U:
22800 case TYPE_LOAD_EXT_UX:
22801 case TYPE_STORE_UX:
22814 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22815 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22818 is_costly_group (rtx *group_insns, rtx next_insn)
22821 int issue_rate = rs6000_issue_rate ();
22823 for (i = 0; i < issue_rate; i++)
22825 sd_iterator_def sd_it;
22827 rtx insn = group_insns[i];
22832 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22834 rtx next = DEP_CON (dep);
22836 if (next == next_insn
22837 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22845 /* Utility of the function redefine_groups.
22846 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22847 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22848 to keep it "far" (in a separate group) from GROUP_INSNS, following
22849 one of the following schemes, depending on the value of the flag
22850 -minsert_sched_nops = X:
22851 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22852 in order to force NEXT_INSN into a separate group.
22853 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22854 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22855 insertion (has a group just ended, how many vacant issue slots remain in the
22856 last group, and how many dispatch groups were encountered so far). */
22859 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22860 rtx next_insn, bool *group_end, int can_issue_more,
22865 int issue_rate = rs6000_issue_rate ();
22866 bool end = *group_end;
22869 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22870 return can_issue_more;
22872 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22873 return can_issue_more;
22875 force = is_costly_group (group_insns, next_insn);
22877 return can_issue_more;
22879 if (sched_verbose > 6)
22880 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22881 *group_count ,can_issue_more);
22883 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22886 can_issue_more = 0;
22888 /* Since only a branch can be issued in the last issue_slot, it is
22889 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22890 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22891 in this case the last nop will start a new group and the branch
22892 will be forced to the new group. */
22893 if (can_issue_more && !is_branch_slot_insn (next_insn))
22896 while (can_issue_more > 0)
22899 emit_insn_before (nop, next_insn);
22907 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22909 int n_nops = rs6000_sched_insert_nops;
22911 /* Nops can't be issued from the branch slot, so the effective
22912 issue_rate for nops is 'issue_rate - 1'. */
22913 if (can_issue_more == 0)
22914 can_issue_more = issue_rate;
22916 if (can_issue_more == 0)
22918 can_issue_more = issue_rate - 1;
22921 for (i = 0; i < issue_rate; i++)
22923 group_insns[i] = 0;
22930 emit_insn_before (nop, next_insn);
22931 if (can_issue_more == issue_rate - 1) /* new group begins */
22934 if (can_issue_more == 0)
22936 can_issue_more = issue_rate - 1;
22939 for (i = 0; i < issue_rate; i++)
22941 group_insns[i] = 0;
22947 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22950 /* Is next_insn going to start a new group? */
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)));
22957 if (*group_end && end)
22960 if (sched_verbose > 6)
22961 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22962 *group_count, can_issue_more);
22963 return can_issue_more;
22966 return can_issue_more;
22969 /* This function tries to synch the dispatch groups that the compiler "sees"
22970 with the dispatch groups that the processor dispatcher is expected to
22971 form in practice. It tries to achieve this synchronization by forcing the
22972 estimated processor grouping on the compiler (as opposed to the function
22973 'pad_goups' which tries to force the scheduler's grouping on the processor).
22975 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22976 examines the (estimated) dispatch groups that will be formed by the processor
22977 dispatcher. It marks these group boundaries to reflect the estimated
22978 processor grouping, overriding the grouping that the scheduler had marked.
22979 Depending on the value of the flag '-minsert-sched-nops' this function can
22980 force certain insns into separate groups or force a certain distance between
22981 them by inserting nops, for example, if there exists a "costly dependence"
22984 The function estimates the group boundaries that the processor will form as
22985 follows: It keeps track of how many vacant issue slots are available after
22986 each insn. A subsequent insn will start a new group if one of the following
22988 - no more vacant issue slots remain in the current dispatch group.
22989 - only the last issue slot, which is the branch slot, is vacant, but the next
22990 insn is not a branch.
22991 - only the last 2 or less issue slots, including the branch slot, are vacant,
22992 which means that a cracked insn (which occupies two issue slots) can't be
22993 issued in this group.
22994 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22995 start a new group. */
22998 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23000 rtx insn, next_insn;
23002 int can_issue_more;
23005 int group_count = 0;
23009 issue_rate = rs6000_issue_rate ();
23010 group_insns = XALLOCAVEC (rtx, issue_rate);
23011 for (i = 0; i < issue_rate; i++)
23013 group_insns[i] = 0;
23015 can_issue_more = issue_rate;
23017 insn = get_next_active_insn (prev_head_insn, tail);
23020 while (insn != NULL_RTX)
23022 slot = (issue_rate - can_issue_more);
23023 group_insns[slot] = insn;
23025 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23026 if (insn_terminates_group_p (insn, current_group))
23027 can_issue_more = 0;
23029 next_insn = get_next_active_insn (insn, tail);
23030 if (next_insn == NULL_RTX)
23031 return group_count + 1;
23033 /* Is next_insn going to start a new group? */
23035 = (can_issue_more == 0
23036 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23037 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23038 || (can_issue_more < issue_rate &&
23039 insn_terminates_group_p (next_insn, previous_group)));
23041 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23042 next_insn, &group_end, can_issue_more,
23048 can_issue_more = 0;
23049 for (i = 0; i < issue_rate; i++)
23051 group_insns[i] = 0;
23055 if (GET_MODE (next_insn) == TImode && can_issue_more)
23056 PUT_MODE (next_insn, VOIDmode);
23057 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23058 PUT_MODE (next_insn, TImode);
23061 if (can_issue_more == 0)
23062 can_issue_more = issue_rate;
23065 return group_count;
23068 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23069 dispatch group boundaries that the scheduler had marked. Pad with nops
23070 any dispatch groups which have vacant issue slots, in order to force the
23071 scheduler's grouping on the processor dispatcher. The function
23072 returns the number of dispatch groups found. */
23075 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23077 rtx insn, next_insn;
23080 int can_issue_more;
23082 int group_count = 0;
23084 /* Initialize issue_rate. */
23085 issue_rate = rs6000_issue_rate ();
23086 can_issue_more = issue_rate;
23088 insn = get_next_active_insn (prev_head_insn, tail);
23089 next_insn = get_next_active_insn (insn, tail);
23091 while (insn != NULL_RTX)
23094 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23096 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23098 if (next_insn == NULL_RTX)
23103 /* If the scheduler had marked group termination at this location
23104 (between insn and next_insn), and neither insn nor next_insn will
23105 force group termination, pad the group with nops to force group
23108 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23109 && !insn_terminates_group_p (insn, current_group)
23110 && !insn_terminates_group_p (next_insn, previous_group))
23112 if (!is_branch_slot_insn (next_insn))
23115 while (can_issue_more)
23118 emit_insn_before (nop, next_insn);
23123 can_issue_more = issue_rate;
23128 next_insn = get_next_active_insn (insn, tail);
23131 return group_count;
23134 /* We're beginning a new block. Initialize data structures as necessary. */
23137 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23138 int sched_verbose ATTRIBUTE_UNUSED,
23139 int max_ready ATTRIBUTE_UNUSED)
23141 last_scheduled_insn = NULL_RTX;
23142 load_store_pendulum = 0;
23145 /* The following function is called at the end of scheduling BB.
23146 After reload, it inserts nops at insn group bundling. */
23149 rs6000_sched_finish (FILE *dump, int sched_verbose)
23154 fprintf (dump, "=== Finishing schedule.\n");
23156 if (reload_completed && rs6000_sched_groups)
23158 /* Do not run sched_finish hook when selective scheduling enabled. */
23159 if (sel_sched_p ())
23162 if (rs6000_sched_insert_nops == sched_finish_none)
23165 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23166 n_groups = pad_groups (dump, sched_verbose,
23167 current_sched_info->prev_head,
23168 current_sched_info->next_tail);
23170 n_groups = redefine_groups (dump, sched_verbose,
23171 current_sched_info->prev_head,
23172 current_sched_info->next_tail);
23174 if (sched_verbose >= 6)
23176 fprintf (dump, "ngroups = %d\n", n_groups);
23177 print_rtl (dump, current_sched_info->prev_head);
23178 fprintf (dump, "Done finish_sched\n");
23183 struct _rs6000_sched_context
23185 short cached_can_issue_more;
23186 rtx last_scheduled_insn;
23187 int load_store_pendulum;
23190 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23191 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23193 /* Allocate store for new scheduling context. */
23195 rs6000_alloc_sched_context (void)
23197 return xmalloc (sizeof (rs6000_sched_context_def));
23200 /* If CLEAN_P is true then initializes _SC with clean data,
23201 and from the global context otherwise. */
23203 rs6000_init_sched_context (void *_sc, bool clean_p)
23205 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23209 sc->cached_can_issue_more = 0;
23210 sc->last_scheduled_insn = NULL_RTX;
23211 sc->load_store_pendulum = 0;
23215 sc->cached_can_issue_more = cached_can_issue_more;
23216 sc->last_scheduled_insn = last_scheduled_insn;
23217 sc->load_store_pendulum = load_store_pendulum;
23221 /* Sets the global scheduling context to the one pointed to by _SC. */
23223 rs6000_set_sched_context (void *_sc)
23225 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23227 gcc_assert (sc != NULL);
23229 cached_can_issue_more = sc->cached_can_issue_more;
23230 last_scheduled_insn = sc->last_scheduled_insn;
23231 load_store_pendulum = sc->load_store_pendulum;
23236 rs6000_free_sched_context (void *_sc)
23238 gcc_assert (_sc != NULL);
23244 /* Length in units of the trampoline for entering a nested function. */
23247 rs6000_trampoline_size (void)
23251 switch (DEFAULT_ABI)
23254 gcc_unreachable ();
23257 ret = (TARGET_32BIT) ? 12 : 24;
23262 ret = (TARGET_32BIT) ? 40 : 48;
23269 /* Emit RTL insns to initialize the variable parts of a trampoline.
23270 FNADDR is an RTX for the address of the function's pure code.
23271 CXT is an RTX for the static chain value for the function. */
23274 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23276 int regsize = (TARGET_32BIT) ? 4 : 8;
23277 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23278 rtx ctx_reg = force_reg (Pmode, cxt);
23279 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23281 switch (DEFAULT_ABI)
23284 gcc_unreachable ();
23286 /* Under AIX, just build the 3 word function descriptor */
23289 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23290 rtx fn_reg = gen_reg_rtx (Pmode);
23291 rtx toc_reg = gen_reg_rtx (Pmode);
23293 /* Macro to shorten the code expansions below. */
23294 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23296 m_tramp = replace_equiv_address (m_tramp, addr);
23298 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23299 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23300 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23301 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23302 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23308 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23311 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23312 LCT_NORMAL, VOIDmode, 4,
23314 GEN_INT (rs6000_trampoline_size ()), SImode,
23322 /* Handle the "altivec" attribute. The attribute may have
23323 arguments as follows:
23325 __attribute__((altivec(vector__)))
23326 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23327 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23329 and may appear more than once (e.g., 'vector bool char') in a
23330 given declaration. */
23333 rs6000_handle_altivec_attribute (tree *node,
23334 tree name ATTRIBUTE_UNUSED,
23336 int flags ATTRIBUTE_UNUSED,
23337 bool *no_add_attrs)
23339 tree type = *node, result = NULL_TREE;
23340 enum machine_mode mode;
23343 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23344 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23345 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23348 while (POINTER_TYPE_P (type)
23349 || TREE_CODE (type) == FUNCTION_TYPE
23350 || TREE_CODE (type) == METHOD_TYPE
23351 || TREE_CODE (type) == ARRAY_TYPE)
23352 type = TREE_TYPE (type);
23354 mode = TYPE_MODE (type);
23356 /* Check for invalid AltiVec type qualifiers. */
23357 if (type == long_double_type_node)
23358 error ("use of %<long double%> in AltiVec types is invalid");
23359 else if (type == boolean_type_node)
23360 error ("use of boolean types in AltiVec types is invalid");
23361 else if (TREE_CODE (type) == COMPLEX_TYPE)
23362 error ("use of %<complex%> in AltiVec types is invalid");
23363 else if (DECIMAL_FLOAT_MODE_P (mode))
23364 error ("use of decimal floating point types in AltiVec types is invalid");
23365 else if (!TARGET_VSX)
23367 if (type == long_unsigned_type_node || type == long_integer_type_node)
23370 error ("use of %<long%> in AltiVec types is invalid for "
23371 "64-bit code without -mvsx");
23372 else if (rs6000_warn_altivec_long)
23373 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23376 else if (type == long_long_unsigned_type_node
23377 || type == long_long_integer_type_node)
23378 error ("use of %<long long%> in AltiVec types is invalid without "
23380 else if (type == double_type_node)
23381 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23384 switch (altivec_type)
23387 unsigned_p = TYPE_UNSIGNED (type);
23391 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23394 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23397 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23400 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23402 case SFmode: result = V4SF_type_node; break;
23403 case DFmode: result = V2DF_type_node; break;
23404 /* If the user says 'vector int bool', we may be handed the 'bool'
23405 attribute _before_ the 'vector' attribute, and so select the
23406 proper type in the 'b' case below. */
23407 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23408 case V2DImode: case V2DFmode:
23416 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23417 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23418 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23419 case QImode: case V16QImode: result = bool_V16QI_type_node;
23426 case V8HImode: result = pixel_V8HI_type_node;
23432 /* Propagate qualifiers attached to the element type
23433 onto the vector type. */
23434 if (result && result != type && TYPE_QUALS (type))
23435 result = build_qualified_type (result, TYPE_QUALS (type));
23437 *no_add_attrs = true; /* No need to hang on to the attribute. */
23440 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23445 /* AltiVec defines four built-in scalar types that serve as vector
23446 elements; we must teach the compiler how to mangle them. */
23448 static const char *
23449 rs6000_mangle_type (const_tree type)
23451 type = TYPE_MAIN_VARIANT (type);
23453 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23454 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23457 if (type == bool_char_type_node) return "U6__boolc";
23458 if (type == bool_short_type_node) return "U6__bools";
23459 if (type == pixel_type_node) return "u7__pixel";
23460 if (type == bool_int_type_node) return "U6__booli";
23461 if (type == bool_long_type_node) return "U6__booll";
23463 /* Mangle IBM extended float long double as `g' (__float128) on
23464 powerpc*-linux where long-double-64 previously was the default. */
23465 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23467 && TARGET_LONG_DOUBLE_128
23468 && !TARGET_IEEEQUAD)
23471 /* For all other types, use normal C++ mangling. */
23475 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23476 struct attribute_spec.handler. */
23479 rs6000_handle_longcall_attribute (tree *node, tree name,
23480 tree args ATTRIBUTE_UNUSED,
23481 int flags ATTRIBUTE_UNUSED,
23482 bool *no_add_attrs)
23484 if (TREE_CODE (*node) != FUNCTION_TYPE
23485 && TREE_CODE (*node) != FIELD_DECL
23486 && TREE_CODE (*node) != TYPE_DECL)
23488 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23490 *no_add_attrs = true;
23496 /* Set longcall attributes on all functions declared when
23497 rs6000_default_long_calls is true. */
23499 rs6000_set_default_type_attributes (tree type)
23501 if (rs6000_default_long_calls
23502 && (TREE_CODE (type) == FUNCTION_TYPE
23503 || TREE_CODE (type) == METHOD_TYPE))
23504 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23506 TYPE_ATTRIBUTES (type));
23509 darwin_set_default_type_attributes (type);
23513 /* Return a reference suitable for calling a function with the
23514 longcall attribute. */
23517 rs6000_longcall_ref (rtx call_ref)
23519 const char *call_name;
23522 if (GET_CODE (call_ref) != SYMBOL_REF)
23525 /* System V adds '.' to the internal name, so skip them. */
23526 call_name = XSTR (call_ref, 0);
23527 if (*call_name == '.')
23529 while (*call_name == '.')
23532 node = get_identifier (call_name);
23533 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23536 return force_reg (Pmode, call_ref);
23539 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23540 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23543 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23544 struct attribute_spec.handler. */
23546 rs6000_handle_struct_attribute (tree *node, tree name,
23547 tree args ATTRIBUTE_UNUSED,
23548 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23551 if (DECL_P (*node))
23553 if (TREE_CODE (*node) == TYPE_DECL)
23554 type = &TREE_TYPE (*node);
23559 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23560 || TREE_CODE (*type) == UNION_TYPE)))
23562 warning (OPT_Wattributes, "%qE attribute ignored", name);
23563 *no_add_attrs = true;
23566 else if ((is_attribute_p ("ms_struct", name)
23567 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23568 || ((is_attribute_p ("gcc_struct", name)
23569 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23571 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23573 *no_add_attrs = true;
23580 rs6000_ms_bitfield_layout_p (const_tree record_type)
23582 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23583 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23584 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23587 #ifdef USING_ELFOS_H
23589 /* A get_unnamed_section callback, used for switching to toc_section. */
23592 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23594 if (DEFAULT_ABI == ABI_AIX
23595 && TARGET_MINIMAL_TOC
23596 && !TARGET_RELOCATABLE)
23598 if (!toc_initialized)
23600 toc_initialized = 1;
23601 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23602 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23603 fprintf (asm_out_file, "\t.tc ");
23604 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23605 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23606 fprintf (asm_out_file, "\n");
23608 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23609 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23610 fprintf (asm_out_file, " = .+32768\n");
23613 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23615 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23616 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23619 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23620 if (!toc_initialized)
23622 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23623 fprintf (asm_out_file, " = .+32768\n");
23624 toc_initialized = 1;
23629 /* Implement TARGET_ASM_INIT_SECTIONS. */
23632 rs6000_elf_asm_init_sections (void)
23635 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23638 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23639 SDATA2_SECTION_ASM_OP);
23642 /* Implement TARGET_SELECT_RTX_SECTION. */
23645 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23646 unsigned HOST_WIDE_INT align)
23648 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23649 return toc_section;
23651 return default_elf_select_rtx_section (mode, x, align);
23654 /* For a SYMBOL_REF, set generic flags and then perform some
23655 target-specific processing.
23657 When the AIX ABI is requested on a non-AIX system, replace the
23658 function name with the real name (with a leading .) rather than the
23659 function descriptor name. This saves a lot of overriding code to
23660 read the prefixes. */
23663 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23665 default_encode_section_info (decl, rtl, first);
23668 && TREE_CODE (decl) == FUNCTION_DECL
23670 && DEFAULT_ABI == ABI_AIX)
23672 rtx sym_ref = XEXP (rtl, 0);
23673 size_t len = strlen (XSTR (sym_ref, 0));
23674 char *str = XALLOCAVEC (char, len + 2);
23676 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23677 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23682 compare_section_name (const char *section, const char *templ)
23686 len = strlen (templ);
23687 return (strncmp (section, templ, len) == 0
23688 && (section[len] == 0 || section[len] == '.'));
23692 rs6000_elf_in_small_data_p (const_tree decl)
23694 if (rs6000_sdata == SDATA_NONE)
23697 /* We want to merge strings, so we never consider them small data. */
23698 if (TREE_CODE (decl) == STRING_CST)
23701 /* Functions are never in the small data area. */
23702 if (TREE_CODE (decl) == FUNCTION_DECL)
23705 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23707 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23708 if (compare_section_name (section, ".sdata")
23709 || compare_section_name (section, ".sdata2")
23710 || compare_section_name (section, ".gnu.linkonce.s")
23711 || compare_section_name (section, ".sbss")
23712 || compare_section_name (section, ".sbss2")
23713 || compare_section_name (section, ".gnu.linkonce.sb")
23714 || strcmp (section, ".PPC.EMB.sdata0") == 0
23715 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23720 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23723 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23724 /* If it's not public, and we're not going to reference it there,
23725 there's no need to put it in the small data section. */
23726 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23733 #endif /* USING_ELFOS_H */
23735 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23738 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23740 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23743 /* Return a REG that occurs in ADDR with coefficient 1.
23744 ADDR can be effectively incremented by incrementing REG.
23746 r0 is special and we must not select it as an address
23747 register by this routine since our caller will try to
23748 increment the returned register via an "la" instruction. */
23751 find_addr_reg (rtx addr)
23753 while (GET_CODE (addr) == PLUS)
23755 if (GET_CODE (XEXP (addr, 0)) == REG
23756 && REGNO (XEXP (addr, 0)) != 0)
23757 addr = XEXP (addr, 0);
23758 else if (GET_CODE (XEXP (addr, 1)) == REG
23759 && REGNO (XEXP (addr, 1)) != 0)
23760 addr = XEXP (addr, 1);
23761 else if (CONSTANT_P (XEXP (addr, 0)))
23762 addr = XEXP (addr, 1);
23763 else if (CONSTANT_P (XEXP (addr, 1)))
23764 addr = XEXP (addr, 0);
23766 gcc_unreachable ();
23768 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23773 rs6000_fatal_bad_address (rtx op)
23775 fatal_insn ("bad address", op);
23780 static tree branch_island_list = 0;
23782 /* Remember to generate a branch island for far calls to the given
23786 add_compiler_branch_island (tree label_name, tree function_name,
23789 tree branch_island = build_tree_list (function_name, label_name);
23790 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23791 TREE_CHAIN (branch_island) = branch_island_list;
23792 branch_island_list = branch_island;
23795 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23796 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23797 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23798 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23800 /* Generate far-jump branch islands for everything on the
23801 branch_island_list. Invoked immediately after the last instruction
23802 of the epilogue has been emitted; the branch-islands must be
23803 appended to, and contiguous with, the function body. Mach-O stubs
23804 are generated in machopic_output_stub(). */
23807 macho_branch_islands (void)
23810 tree branch_island;
23812 for (branch_island = branch_island_list;
23814 branch_island = TREE_CHAIN (branch_island))
23816 const char *label =
23817 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23819 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23820 char name_buf[512];
23821 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23822 if (name[0] == '*' || name[0] == '&')
23823 strcpy (name_buf, name+1);
23827 strcpy (name_buf+1, name);
23829 strcpy (tmp_buf, "\n");
23830 strcat (tmp_buf, label);
23831 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23832 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23833 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23834 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23837 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23838 strcat (tmp_buf, label);
23839 strcat (tmp_buf, "_pic\n");
23840 strcat (tmp_buf, label);
23841 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23843 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23844 strcat (tmp_buf, name_buf);
23845 strcat (tmp_buf, " - ");
23846 strcat (tmp_buf, label);
23847 strcat (tmp_buf, "_pic)\n");
23849 strcat (tmp_buf, "\tmtlr r0\n");
23851 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23852 strcat (tmp_buf, name_buf);
23853 strcat (tmp_buf, " - ");
23854 strcat (tmp_buf, label);
23855 strcat (tmp_buf, "_pic)\n");
23857 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23861 strcat (tmp_buf, ":\nlis r12,hi16(");
23862 strcat (tmp_buf, name_buf);
23863 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23864 strcat (tmp_buf, name_buf);
23865 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23867 output_asm_insn (tmp_buf, 0);
23868 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23869 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23870 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23871 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23874 branch_island_list = 0;
23877 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23878 already there or not. */
23881 no_previous_def (tree function_name)
23883 tree branch_island;
23884 for (branch_island = branch_island_list;
23886 branch_island = TREE_CHAIN (branch_island))
23887 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23892 /* GET_PREV_LABEL gets the label name from the previous definition of
23896 get_prev_label (tree function_name)
23898 tree branch_island;
23899 for (branch_island = branch_island_list;
23901 branch_island = TREE_CHAIN (branch_island))
23902 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23903 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23907 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23908 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23911 /* KEXTs still need branch islands. */
23912 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23913 || flag_mkernel || flag_apple_kext)
23915 /* INSN is either a function call or a millicode call. It may have an
23916 unconditional jump in its delay slot.
23918 CALL_DEST is the routine we are calling. */
23921 output_call (rtx insn, rtx *operands, int dest_operand_number,
23922 int cookie_operand_number)
23924 static char buf[256];
23925 if (DARWIN_GENERATE_ISLANDS
23926 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23927 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23930 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23932 if (no_previous_def (funname))
23934 rtx label_rtx = gen_label_rtx ();
23935 char *label_buf, temp_buf[256];
23936 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23937 CODE_LABEL_NUMBER (label_rtx));
23938 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23939 labelname = get_identifier (label_buf);
23940 add_compiler_branch_island (labelname, funname, insn_line (insn));
23943 labelname = get_prev_label (funname);
23945 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23946 instruction will reach 'foo', otherwise link as 'bl L42'".
23947 "L42" should be a 'branch island', that will do a far jump to
23948 'foo'. Branch islands are generated in
23949 macho_branch_islands(). */
23950 sprintf (buf, "jbsr %%z%d,%.246s",
23951 dest_operand_number, IDENTIFIER_POINTER (labelname));
23954 sprintf (buf, "bl %%z%d", dest_operand_number);
23958 /* Generate PIC and indirect symbol stubs. */
23961 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23963 unsigned int length;
23964 char *symbol_name, *lazy_ptr_name;
23965 char *local_label_0;
23966 static int label = 0;
23968 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23969 symb = (*targetm.strip_name_encoding) (symb);
23972 length = strlen (symb);
23973 symbol_name = XALLOCAVEC (char, length + 32);
23974 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23976 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23977 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23980 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23982 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23986 fprintf (file, "\t.align 5\n");
23988 fprintf (file, "%s:\n", stub);
23989 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23992 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23993 sprintf (local_label_0, "\"L%011d$spb\"", label);
23995 fprintf (file, "\tmflr r0\n");
23996 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23997 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23998 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23999 lazy_ptr_name, local_label_0);
24000 fprintf (file, "\tmtlr r0\n");
24001 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24002 (TARGET_64BIT ? "ldu" : "lwzu"),
24003 lazy_ptr_name, local_label_0);
24004 fprintf (file, "\tmtctr r12\n");
24005 fprintf (file, "\tbctr\n");
24009 fprintf (file, "\t.align 4\n");
24011 fprintf (file, "%s:\n", stub);
24012 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24014 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24015 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24016 (TARGET_64BIT ? "ldu" : "lwzu"),
24018 fprintf (file, "\tmtctr r12\n");
24019 fprintf (file, "\tbctr\n");
24022 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24023 fprintf (file, "%s:\n", lazy_ptr_name);
24024 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24025 fprintf (file, "%sdyld_stub_binding_helper\n",
24026 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24029 /* Legitimize PIC addresses. If the address is already
24030 position-independent, we return ORIG. Newly generated
24031 position-independent addresses go into a reg. This is REG if non
24032 zero, otherwise we allocate register(s) as necessary. */
24034 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24037 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24042 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24043 reg = gen_reg_rtx (Pmode);
24045 if (GET_CODE (orig) == CONST)
24049 if (GET_CODE (XEXP (orig, 0)) == PLUS
24050 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24053 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24055 /* Use a different reg for the intermediate value, as
24056 it will be marked UNCHANGING. */
24057 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24058 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24061 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24064 if (GET_CODE (offset) == CONST_INT)
24066 if (SMALL_INT (offset))
24067 return plus_constant (base, INTVAL (offset));
24068 else if (! reload_in_progress && ! reload_completed)
24069 offset = force_reg (Pmode, offset);
24072 rtx mem = force_const_mem (Pmode, orig);
24073 return machopic_legitimize_pic_address (mem, Pmode, reg);
24076 return gen_rtx_PLUS (Pmode, base, offset);
24079 /* Fall back on generic machopic code. */
24080 return machopic_legitimize_pic_address (orig, mode, reg);
24083 /* Output a .machine directive for the Darwin assembler, and call
24084 the generic start_file routine. */
24087 rs6000_darwin_file_start (void)
24089 static const struct
24095 { "ppc64", "ppc64", MASK_64BIT },
24096 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24097 { "power4", "ppc970", 0 },
24098 { "G5", "ppc970", 0 },
24099 { "7450", "ppc7450", 0 },
24100 { "7400", "ppc7400", MASK_ALTIVEC },
24101 { "G4", "ppc7400", 0 },
24102 { "750", "ppc750", 0 },
24103 { "740", "ppc750", 0 },
24104 { "G3", "ppc750", 0 },
24105 { "604e", "ppc604e", 0 },
24106 { "604", "ppc604", 0 },
24107 { "603e", "ppc603", 0 },
24108 { "603", "ppc603", 0 },
24109 { "601", "ppc601", 0 },
24110 { NULL, "ppc", 0 } };
24111 const char *cpu_id = "";
24114 rs6000_file_start ();
24115 darwin_file_start ();
24117 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24118 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24119 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24120 && rs6000_select[i].string[0] != '\0')
24121 cpu_id = rs6000_select[i].string;
24123 /* Look through the mapping array. Pick the first name that either
24124 matches the argument, has a bit set in IF_SET that is also set
24125 in the target flags, or has a NULL name. */
24128 while (mapping[i].arg != NULL
24129 && strcmp (mapping[i].arg, cpu_id) != 0
24130 && (mapping[i].if_set & target_flags) == 0)
24133 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24136 #endif /* TARGET_MACHO */
24140 rs6000_elf_reloc_rw_mask (void)
24144 else if (DEFAULT_ABI == ABI_AIX)
24150 /* Record an element in the table of global constructors. SYMBOL is
24151 a SYMBOL_REF of the function to be called; PRIORITY is a number
24152 between 0 and MAX_INIT_PRIORITY.
24154 This differs from default_named_section_asm_out_constructor in
24155 that we have special handling for -mrelocatable. */
24158 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24160 const char *section = ".ctors";
24163 if (priority != DEFAULT_INIT_PRIORITY)
24165 sprintf (buf, ".ctors.%.5u",
24166 /* Invert the numbering so the linker puts us in the proper
24167 order; constructors are run from right to left, and the
24168 linker sorts in increasing order. */
24169 MAX_INIT_PRIORITY - priority);
24173 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24174 assemble_align (POINTER_SIZE);
24176 if (TARGET_RELOCATABLE)
24178 fputs ("\t.long (", asm_out_file);
24179 output_addr_const (asm_out_file, symbol);
24180 fputs (")@fixup\n", asm_out_file);
24183 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24187 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24189 const char *section = ".dtors";
24192 if (priority != DEFAULT_INIT_PRIORITY)
24194 sprintf (buf, ".dtors.%.5u",
24195 /* Invert the numbering so the linker puts us in the proper
24196 order; constructors are run from right to left, and the
24197 linker sorts in increasing order. */
24198 MAX_INIT_PRIORITY - priority);
24202 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24203 assemble_align (POINTER_SIZE);
24205 if (TARGET_RELOCATABLE)
24207 fputs ("\t.long (", asm_out_file);
24208 output_addr_const (asm_out_file, symbol);
24209 fputs (")@fixup\n", asm_out_file);
24212 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24216 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24220 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24221 ASM_OUTPUT_LABEL (file, name);
24222 fputs (DOUBLE_INT_ASM_OP, file);
24223 rs6000_output_function_entry (file, name);
24224 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24227 fputs ("\t.size\t", file);
24228 assemble_name (file, name);
24229 fputs (",24\n\t.type\t.", file);
24230 assemble_name (file, name);
24231 fputs (",@function\n", file);
24232 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24234 fputs ("\t.globl\t.", file);
24235 assemble_name (file, name);
24240 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24241 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24242 rs6000_output_function_entry (file, name);
24243 fputs (":\n", file);
24247 if (TARGET_RELOCATABLE
24248 && !TARGET_SECURE_PLT
24249 && (get_pool_size () != 0 || crtl->profile)
24254 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24256 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24257 fprintf (file, "\t.long ");
24258 assemble_name (file, buf);
24260 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24261 assemble_name (file, buf);
24265 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24266 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24268 if (DEFAULT_ABI == ABI_AIX)
24270 const char *desc_name, *orig_name;
24272 orig_name = (*targetm.strip_name_encoding) (name);
24273 desc_name = orig_name;
24274 while (*desc_name == '.')
24277 if (TREE_PUBLIC (decl))
24278 fprintf (file, "\t.globl %s\n", desc_name);
24280 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24281 fprintf (file, "%s:\n", desc_name);
24282 fprintf (file, "\t.long %s\n", orig_name);
24283 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24284 if (DEFAULT_ABI == ABI_AIX)
24285 fputs ("\t.long 0\n", file);
24286 fprintf (file, "\t.previous\n");
24288 ASM_OUTPUT_LABEL (file, name);
24292 rs6000_elf_end_indicate_exec_stack (void)
24295 file_end_indicate_exec_stack ();
24301 rs6000_xcoff_asm_output_anchor (rtx symbol)
24305 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24306 SYMBOL_REF_BLOCK_OFFSET (symbol));
24307 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24311 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24313 fputs (GLOBAL_ASM_OP, stream);
24314 RS6000_OUTPUT_BASENAME (stream, name);
24315 putc ('\n', stream);
24318 /* A get_unnamed_decl callback, used for read-only sections. PTR
24319 points to the section string variable. */
24322 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24324 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24325 *(const char *const *) directive,
24326 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24329 /* Likewise for read-write sections. */
24332 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24334 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24335 *(const char *const *) directive,
24336 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24339 /* A get_unnamed_section callback, used for switching to toc_section. */
24342 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24344 if (TARGET_MINIMAL_TOC)
24346 /* toc_section is always selected at least once from
24347 rs6000_xcoff_file_start, so this is guaranteed to
24348 always be defined once and only once in each file. */
24349 if (!toc_initialized)
24351 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24352 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24353 toc_initialized = 1;
24355 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24356 (TARGET_32BIT ? "" : ",3"));
24359 fputs ("\t.toc\n", asm_out_file);
24362 /* Implement TARGET_ASM_INIT_SECTIONS. */
24365 rs6000_xcoff_asm_init_sections (void)
24367 read_only_data_section
24368 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24369 &xcoff_read_only_section_name);
24371 private_data_section
24372 = get_unnamed_section (SECTION_WRITE,
24373 rs6000_xcoff_output_readwrite_section_asm_op,
24374 &xcoff_private_data_section_name);
24376 read_only_private_data_section
24377 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24378 &xcoff_private_data_section_name);
24381 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24383 readonly_data_section = read_only_data_section;
24384 exception_section = data_section;
24388 rs6000_xcoff_reloc_rw_mask (void)
24394 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24395 tree decl ATTRIBUTE_UNUSED)
24398 static const char * const suffix[3] = { "PR", "RO", "RW" };
24400 if (flags & SECTION_CODE)
24402 else if (flags & SECTION_WRITE)
24407 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24408 (flags & SECTION_CODE) ? "." : "",
24409 name, suffix[smclass], flags & SECTION_ENTSIZE);
24413 rs6000_xcoff_select_section (tree decl, int reloc,
24414 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24416 if (decl_readonly_section (decl, reloc))
24418 if (TREE_PUBLIC (decl))
24419 return read_only_data_section;
24421 return read_only_private_data_section;
24425 if (TREE_PUBLIC (decl))
24426 return data_section;
24428 return private_data_section;
24433 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24437 /* Use select_section for private and uninitialized data. */
24438 if (!TREE_PUBLIC (decl)
24439 || DECL_COMMON (decl)
24440 || DECL_INITIAL (decl) == NULL_TREE
24441 || DECL_INITIAL (decl) == error_mark_node
24442 || (flag_zero_initialized_in_bss
24443 && initializer_zerop (DECL_INITIAL (decl))))
24446 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24447 name = (*targetm.strip_name_encoding) (name);
24448 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24451 /* Select section for constant in constant pool.
24453 On RS/6000, all constants are in the private read-only data area.
24454 However, if this is being placed in the TOC it must be output as a
24458 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24459 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24461 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24462 return toc_section;
24464 return read_only_private_data_section;
24467 /* Remove any trailing [DS] or the like from the symbol name. */
24469 static const char *
24470 rs6000_xcoff_strip_name_encoding (const char *name)
24475 len = strlen (name);
24476 if (name[len - 1] == ']')
24477 return ggc_alloc_string (name, len - 4);
24482 /* Section attributes. AIX is always PIC. */
24484 static unsigned int
24485 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24487 unsigned int align;
24488 unsigned int flags = default_section_type_flags (decl, name, reloc);
24490 /* Align to at least UNIT size. */
24491 if (flags & SECTION_CODE)
24492 align = MIN_UNITS_PER_WORD;
24494 /* Increase alignment of large objects if not already stricter. */
24495 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24496 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24497 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24499 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24502 /* Output at beginning of assembler file.
24504 Initialize the section names for the RS/6000 at this point.
24506 Specify filename, including full path, to assembler.
24508 We want to go into the TOC section so at least one .toc will be emitted.
24509 Also, in order to output proper .bs/.es pairs, we need at least one static
24510 [RW] section emitted.
24512 Finally, declare mcount when profiling to make the assembler happy. */
24515 rs6000_xcoff_file_start (void)
24517 rs6000_gen_section_name (&xcoff_bss_section_name,
24518 main_input_filename, ".bss_");
24519 rs6000_gen_section_name (&xcoff_private_data_section_name,
24520 main_input_filename, ".rw_");
24521 rs6000_gen_section_name (&xcoff_read_only_section_name,
24522 main_input_filename, ".ro_");
24524 fputs ("\t.file\t", asm_out_file);
24525 output_quoted_string (asm_out_file, main_input_filename);
24526 fputc ('\n', asm_out_file);
24527 if (write_symbols != NO_DEBUG)
24528 switch_to_section (private_data_section);
24529 switch_to_section (text_section);
24531 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24532 rs6000_file_start ();
24535 /* Output at end of assembler file.
24536 On the RS/6000, referencing data should automatically pull in text. */
24539 rs6000_xcoff_file_end (void)
24541 switch_to_section (text_section);
24542 fputs ("_section_.text:\n", asm_out_file);
24543 switch_to_section (data_section);
24544 fputs (TARGET_32BIT
24545 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24548 #endif /* TARGET_XCOFF */
24550 /* Compute a (partial) cost for rtx X. Return true if the complete
24551 cost has been computed, and false if subexpressions should be
24552 scanned. In either case, *TOTAL contains the cost result. */
24555 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24558 enum machine_mode mode = GET_MODE (x);
24562 /* On the RS/6000, if it is valid in the insn, it is free. */
24564 if (((outer_code == SET
24565 || outer_code == PLUS
24566 || outer_code == MINUS)
24567 && (satisfies_constraint_I (x)
24568 || satisfies_constraint_L (x)))
24569 || (outer_code == AND
24570 && (satisfies_constraint_K (x)
24572 ? satisfies_constraint_L (x)
24573 : satisfies_constraint_J (x))
24574 || mask_operand (x, mode)
24576 && mask64_operand (x, DImode))))
24577 || ((outer_code == IOR || outer_code == XOR)
24578 && (satisfies_constraint_K (x)
24580 ? satisfies_constraint_L (x)
24581 : satisfies_constraint_J (x))))
24582 || outer_code == ASHIFT
24583 || outer_code == ASHIFTRT
24584 || outer_code == LSHIFTRT
24585 || outer_code == ROTATE
24586 || outer_code == ROTATERT
24587 || outer_code == ZERO_EXTRACT
24588 || (outer_code == MULT
24589 && satisfies_constraint_I (x))
24590 || ((outer_code == DIV || outer_code == UDIV
24591 || outer_code == MOD || outer_code == UMOD)
24592 && exact_log2 (INTVAL (x)) >= 0)
24593 || (outer_code == COMPARE
24594 && (satisfies_constraint_I (x)
24595 || satisfies_constraint_K (x)))
24596 || (outer_code == EQ
24597 && (satisfies_constraint_I (x)
24598 || satisfies_constraint_K (x)
24600 ? satisfies_constraint_L (x)
24601 : satisfies_constraint_J (x))))
24602 || (outer_code == GTU
24603 && satisfies_constraint_I (x))
24604 || (outer_code == LTU
24605 && satisfies_constraint_P (x)))
24610 else if ((outer_code == PLUS
24611 && reg_or_add_cint_operand (x, VOIDmode))
24612 || (outer_code == MINUS
24613 && reg_or_sub_cint_operand (x, VOIDmode))
24614 || ((outer_code == SET
24615 || outer_code == IOR
24616 || outer_code == XOR)
24618 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24620 *total = COSTS_N_INSNS (1);
24626 if (mode == DImode && code == CONST_DOUBLE)
24628 if ((outer_code == IOR || outer_code == XOR)
24629 && CONST_DOUBLE_HIGH (x) == 0
24630 && (CONST_DOUBLE_LOW (x)
24631 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24636 else if ((outer_code == AND && and64_2_operand (x, DImode))
24637 || ((outer_code == SET
24638 || outer_code == IOR
24639 || outer_code == XOR)
24640 && CONST_DOUBLE_HIGH (x) == 0))
24642 *total = COSTS_N_INSNS (1);
24652 /* When optimizing for size, MEM should be slightly more expensive
24653 than generating address, e.g., (plus (reg) (const)).
24654 L1 cache latency is about two instructions. */
24655 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24663 if (mode == DFmode)
24665 if (GET_CODE (XEXP (x, 0)) == MULT)
24667 /* FNMA accounted in outer NEG. */
24668 if (outer_code == NEG)
24669 *total = rs6000_cost->dmul - rs6000_cost->fp;
24671 *total = rs6000_cost->dmul;
24674 *total = rs6000_cost->fp;
24676 else if (mode == SFmode)
24678 /* FNMA accounted in outer NEG. */
24679 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24682 *total = rs6000_cost->fp;
24685 *total = COSTS_N_INSNS (1);
24689 if (mode == DFmode)
24691 if (GET_CODE (XEXP (x, 0)) == MULT
24692 || GET_CODE (XEXP (x, 1)) == MULT)
24694 /* FNMA accounted in outer NEG. */
24695 if (outer_code == NEG)
24696 *total = rs6000_cost->dmul - rs6000_cost->fp;
24698 *total = rs6000_cost->dmul;
24701 *total = rs6000_cost->fp;
24703 else if (mode == SFmode)
24705 /* FNMA accounted in outer NEG. */
24706 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24709 *total = rs6000_cost->fp;
24712 *total = COSTS_N_INSNS (1);
24716 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24717 && satisfies_constraint_I (XEXP (x, 1)))
24719 if (INTVAL (XEXP (x, 1)) >= -256
24720 && INTVAL (XEXP (x, 1)) <= 255)
24721 *total = rs6000_cost->mulsi_const9;
24723 *total = rs6000_cost->mulsi_const;
24725 /* FMA accounted in outer PLUS/MINUS. */
24726 else if ((mode == DFmode || mode == SFmode)
24727 && (outer_code == PLUS || outer_code == MINUS))
24729 else if (mode == DFmode)
24730 *total = rs6000_cost->dmul;
24731 else if (mode == SFmode)
24732 *total = rs6000_cost->fp;
24733 else if (mode == DImode)
24734 *total = rs6000_cost->muldi;
24736 *total = rs6000_cost->mulsi;
24741 if (FLOAT_MODE_P (mode))
24743 *total = mode == DFmode ? rs6000_cost->ddiv
24744 : rs6000_cost->sdiv;
24751 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24752 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24754 if (code == DIV || code == MOD)
24756 *total = COSTS_N_INSNS (2);
24759 *total = COSTS_N_INSNS (1);
24763 if (GET_MODE (XEXP (x, 1)) == DImode)
24764 *total = rs6000_cost->divdi;
24766 *total = rs6000_cost->divsi;
24768 /* Add in shift and subtract for MOD. */
24769 if (code == MOD || code == UMOD)
24770 *total += COSTS_N_INSNS (2);
24775 *total = COSTS_N_INSNS (4);
24779 *total = COSTS_N_INSNS (6);
24783 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24795 *total = COSTS_N_INSNS (1);
24803 /* Handle mul_highpart. */
24804 if (outer_code == TRUNCATE
24805 && GET_CODE (XEXP (x, 0)) == MULT)
24807 if (mode == DImode)
24808 *total = rs6000_cost->muldi;
24810 *total = rs6000_cost->mulsi;
24813 else if (outer_code == AND)
24816 *total = COSTS_N_INSNS (1);
24821 if (GET_CODE (XEXP (x, 0)) == MEM)
24824 *total = COSTS_N_INSNS (1);
24830 if (!FLOAT_MODE_P (mode))
24832 *total = COSTS_N_INSNS (1);
24838 case UNSIGNED_FLOAT:
24841 case FLOAT_TRUNCATE:
24842 *total = rs6000_cost->fp;
24846 if (mode == DFmode)
24849 *total = rs6000_cost->fp;
24853 switch (XINT (x, 1))
24856 *total = rs6000_cost->fp;
24868 *total = COSTS_N_INSNS (1);
24871 else if (FLOAT_MODE_P (mode)
24872 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24874 *total = rs6000_cost->fp;
24882 /* Carry bit requires mode == Pmode.
24883 NEG or PLUS already counted so only add one. */
24885 && (outer_code == NEG || outer_code == PLUS))
24887 *total = COSTS_N_INSNS (1);
24890 if (outer_code == SET)
24892 if (XEXP (x, 1) == const0_rtx)
24894 if (TARGET_ISEL && !TARGET_MFCRF)
24895 *total = COSTS_N_INSNS (8);
24897 *total = COSTS_N_INSNS (2);
24900 else if (mode == Pmode)
24902 *total = COSTS_N_INSNS (3);
24911 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24913 if (TARGET_ISEL && !TARGET_MFCRF)
24914 *total = COSTS_N_INSNS (8);
24916 *total = COSTS_N_INSNS (2);
24920 if (outer_code == COMPARE)
24934 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24937 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24940 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24943 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24944 "total = %d, speed = %s, x:\n",
24945 ret ? "complete" : "scan inner",
24946 GET_RTX_NAME (code),
24947 GET_RTX_NAME (outer_code),
24949 speed ? "true" : "false");
24956 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24959 rs6000_debug_address_cost (rtx x, bool speed)
24961 int ret = TARGET_ADDRESS_COST (x, speed);
24963 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24964 ret, speed ? "true" : "false");
24971 /* A C expression returning the cost of moving data from a register of class
24972 CLASS1 to one of CLASS2. */
24975 rs6000_register_move_cost (enum machine_mode mode,
24976 enum reg_class from, enum reg_class to)
24980 /* Moves from/to GENERAL_REGS. */
24981 if (reg_classes_intersect_p (to, GENERAL_REGS)
24982 || reg_classes_intersect_p (from, GENERAL_REGS))
24984 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24987 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24988 ret = (rs6000_memory_move_cost (mode, from, 0)
24989 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24991 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24993 else if (from == CR_REGS)
24996 /* Power6 has slower LR/CTR moves so make them more expensive than
24997 memory in order to bias spills to memory .*/
24998 else if (rs6000_cpu == PROCESSOR_POWER6
24999 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25000 ret = 6 * hard_regno_nregs[0][mode];
25003 /* A move will cost one instruction per GPR moved. */
25004 ret = 2 * hard_regno_nregs[0][mode];
25007 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25008 else if (VECTOR_UNIT_VSX_P (mode)
25009 && reg_classes_intersect_p (to, VSX_REGS)
25010 && reg_classes_intersect_p (from, VSX_REGS))
25011 ret = 2 * hard_regno_nregs[32][mode];
25013 /* Moving between two similar registers is just one instruction. */
25014 else if (reg_classes_intersect_p (to, from))
25015 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25017 /* Everything else has to go through GENERAL_REGS. */
25019 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25020 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25022 if (TARGET_DEBUG_COST)
25024 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25025 ret, GET_MODE_NAME (mode), reg_class_names[from],
25026 reg_class_names[to]);
25031 /* A C expressions returning the cost of moving data of MODE from a register to
25035 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25036 int in ATTRIBUTE_UNUSED)
25040 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25041 ret = 4 * hard_regno_nregs[0][mode];
25042 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25043 ret = 4 * hard_regno_nregs[32][mode];
25044 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25045 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25047 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25049 if (TARGET_DEBUG_COST)
25051 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25052 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25057 /* Returns a code for a target-specific builtin that implements
25058 reciprocal of the function, or NULL_TREE if not available. */
25061 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25062 bool sqrt ATTRIBUTE_UNUSED)
25064 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25065 && flag_finite_math_only && !flag_trapping_math
25066 && flag_unsafe_math_optimizations))
25074 case BUILT_IN_SQRTF:
25075 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25082 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25083 Assumes no trapping math and finite arguments. */
25086 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25088 rtx x0, e0, e1, y1, u0, v0, one;
25090 x0 = gen_reg_rtx (SFmode);
25091 e0 = gen_reg_rtx (SFmode);
25092 e1 = gen_reg_rtx (SFmode);
25093 y1 = gen_reg_rtx (SFmode);
25094 u0 = gen_reg_rtx (SFmode);
25095 v0 = gen_reg_rtx (SFmode);
25096 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25098 /* x0 = 1./d estimate */
25099 emit_insn (gen_rtx_SET (VOIDmode, x0,
25100 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25102 /* e0 = 1. - d * x0 */
25103 emit_insn (gen_rtx_SET (VOIDmode, e0,
25104 gen_rtx_MINUS (SFmode, one,
25105 gen_rtx_MULT (SFmode, d, x0))));
25106 /* e1 = e0 + e0 * e0 */
25107 emit_insn (gen_rtx_SET (VOIDmode, e1,
25108 gen_rtx_PLUS (SFmode,
25109 gen_rtx_MULT (SFmode, e0, e0), e0)));
25110 /* y1 = x0 + e1 * x0 */
25111 emit_insn (gen_rtx_SET (VOIDmode, y1,
25112 gen_rtx_PLUS (SFmode,
25113 gen_rtx_MULT (SFmode, e1, x0), x0)));
25115 emit_insn (gen_rtx_SET (VOIDmode, u0,
25116 gen_rtx_MULT (SFmode, n, y1)));
25117 /* v0 = n - d * u0 */
25118 emit_insn (gen_rtx_SET (VOIDmode, v0,
25119 gen_rtx_MINUS (SFmode, n,
25120 gen_rtx_MULT (SFmode, d, u0))));
25121 /* dst = u0 + v0 * y1 */
25122 emit_insn (gen_rtx_SET (VOIDmode, dst,
25123 gen_rtx_PLUS (SFmode,
25124 gen_rtx_MULT (SFmode, v0, y1), u0)));
25127 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25128 Assumes no trapping math and finite arguments. */
25131 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25133 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25135 x0 = gen_reg_rtx (DFmode);
25136 e0 = gen_reg_rtx (DFmode);
25137 e1 = gen_reg_rtx (DFmode);
25138 e2 = gen_reg_rtx (DFmode);
25139 y1 = gen_reg_rtx (DFmode);
25140 y2 = gen_reg_rtx (DFmode);
25141 y3 = gen_reg_rtx (DFmode);
25142 u0 = gen_reg_rtx (DFmode);
25143 v0 = gen_reg_rtx (DFmode);
25144 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25146 /* x0 = 1./d estimate */
25147 emit_insn (gen_rtx_SET (VOIDmode, x0,
25148 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25150 /* e0 = 1. - d * x0 */
25151 emit_insn (gen_rtx_SET (VOIDmode, e0,
25152 gen_rtx_MINUS (DFmode, one,
25153 gen_rtx_MULT (SFmode, d, x0))));
25154 /* y1 = x0 + e0 * x0 */
25155 emit_insn (gen_rtx_SET (VOIDmode, y1,
25156 gen_rtx_PLUS (DFmode,
25157 gen_rtx_MULT (DFmode, e0, x0), x0)));
25159 emit_insn (gen_rtx_SET (VOIDmode, e1,
25160 gen_rtx_MULT (DFmode, e0, e0)));
25161 /* y2 = y1 + e1 * y1 */
25162 emit_insn (gen_rtx_SET (VOIDmode, y2,
25163 gen_rtx_PLUS (DFmode,
25164 gen_rtx_MULT (DFmode, e1, y1), y1)));
25166 emit_insn (gen_rtx_SET (VOIDmode, e2,
25167 gen_rtx_MULT (DFmode, e1, e1)));
25168 /* y3 = y2 + e2 * y2 */
25169 emit_insn (gen_rtx_SET (VOIDmode, y3,
25170 gen_rtx_PLUS (DFmode,
25171 gen_rtx_MULT (DFmode, e2, y2), y2)));
25173 emit_insn (gen_rtx_SET (VOIDmode, u0,
25174 gen_rtx_MULT (DFmode, n, y3)));
25175 /* v0 = n - d * u0 */
25176 emit_insn (gen_rtx_SET (VOIDmode, v0,
25177 gen_rtx_MINUS (DFmode, n,
25178 gen_rtx_MULT (DFmode, d, u0))));
25179 /* dst = u0 + v0 * y3 */
25180 emit_insn (gen_rtx_SET (VOIDmode, dst,
25181 gen_rtx_PLUS (DFmode,
25182 gen_rtx_MULT (DFmode, v0, y3), u0)));
25186 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25187 Assumes no trapping math and finite arguments. */
25190 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25192 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25193 half, one, halfthree, c1, cond, label;
25195 x0 = gen_reg_rtx (SFmode);
25196 x1 = gen_reg_rtx (SFmode);
25197 x2 = gen_reg_rtx (SFmode);
25198 y1 = gen_reg_rtx (SFmode);
25199 u0 = gen_reg_rtx (SFmode);
25200 u1 = gen_reg_rtx (SFmode);
25201 u2 = gen_reg_rtx (SFmode);
25202 v0 = gen_reg_rtx (SFmode);
25203 v1 = gen_reg_rtx (SFmode);
25204 v2 = gen_reg_rtx (SFmode);
25205 t0 = gen_reg_rtx (SFmode);
25206 halfthree = gen_reg_rtx (SFmode);
25207 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25208 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25210 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25211 emit_insn (gen_rtx_SET (VOIDmode, t0,
25212 gen_rtx_MULT (SFmode, src, src)));
25214 emit_insn (gen_rtx_SET (VOIDmode, cond,
25215 gen_rtx_COMPARE (CCFPmode, t0, src)));
25216 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25217 emit_unlikely_jump (c1, label);
25219 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25220 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25222 /* halfthree = 1.5 = 1.0 + 0.5 */
25223 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25224 gen_rtx_PLUS (SFmode, one, half)));
25226 /* x0 = rsqrt estimate */
25227 emit_insn (gen_rtx_SET (VOIDmode, x0,
25228 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25231 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25232 emit_insn (gen_rtx_SET (VOIDmode, y1,
25233 gen_rtx_MINUS (SFmode,
25234 gen_rtx_MULT (SFmode, src, halfthree),
25237 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25238 emit_insn (gen_rtx_SET (VOIDmode, u0,
25239 gen_rtx_MULT (SFmode, x0, x0)));
25240 emit_insn (gen_rtx_SET (VOIDmode, v0,
25241 gen_rtx_MINUS (SFmode,
25243 gen_rtx_MULT (SFmode, y1, u0))));
25244 emit_insn (gen_rtx_SET (VOIDmode, x1,
25245 gen_rtx_MULT (SFmode, x0, v0)));
25247 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25248 emit_insn (gen_rtx_SET (VOIDmode, u1,
25249 gen_rtx_MULT (SFmode, x1, x1)));
25250 emit_insn (gen_rtx_SET (VOIDmode, v1,
25251 gen_rtx_MINUS (SFmode,
25253 gen_rtx_MULT (SFmode, y1, u1))));
25254 emit_insn (gen_rtx_SET (VOIDmode, x2,
25255 gen_rtx_MULT (SFmode, x1, v1)));
25257 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25258 emit_insn (gen_rtx_SET (VOIDmode, u2,
25259 gen_rtx_MULT (SFmode, x2, x2)));
25260 emit_insn (gen_rtx_SET (VOIDmode, v2,
25261 gen_rtx_MINUS (SFmode,
25263 gen_rtx_MULT (SFmode, y1, u2))));
25264 emit_insn (gen_rtx_SET (VOIDmode, dst,
25265 gen_rtx_MULT (SFmode, x2, v2)));
25267 emit_label (XEXP (label, 0));
25270 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25271 (Power7) targets. DST is the target, and SRC is the argument operand. */
25274 rs6000_emit_popcount (rtx dst, rtx src)
25276 enum machine_mode mode = GET_MODE (dst);
25279 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25280 if (TARGET_POPCNTD)
25282 if (mode == SImode)
25283 emit_insn (gen_popcntwsi2 (dst, src));
25285 emit_insn (gen_popcntddi2 (dst, src));
25289 tmp1 = gen_reg_rtx (mode);
25291 if (mode == SImode)
25293 emit_insn (gen_popcntbsi2 (tmp1, src));
25294 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25296 tmp2 = force_reg (SImode, tmp2);
25297 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25301 emit_insn (gen_popcntbdi2 (tmp1, src));
25302 tmp2 = expand_mult (DImode, tmp1,
25303 GEN_INT ((HOST_WIDE_INT)
25304 0x01010101 << 32 | 0x01010101),
25306 tmp2 = force_reg (DImode, tmp2);
25307 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25312 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25313 target, and SRC is the argument operand. */
25316 rs6000_emit_parity (rtx dst, rtx src)
25318 enum machine_mode mode = GET_MODE (dst);
25321 tmp = gen_reg_rtx (mode);
25322 if (mode == SImode)
25324 /* Is mult+shift >= shift+xor+shift+xor? */
25325 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25327 rtx tmp1, tmp2, tmp3, tmp4;
25329 tmp1 = gen_reg_rtx (SImode);
25330 emit_insn (gen_popcntbsi2 (tmp1, src));
25332 tmp2 = gen_reg_rtx (SImode);
25333 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25334 tmp3 = gen_reg_rtx (SImode);
25335 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25337 tmp4 = gen_reg_rtx (SImode);
25338 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25339 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25342 rs6000_emit_popcount (tmp, src);
25343 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25347 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25348 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25350 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25352 tmp1 = gen_reg_rtx (DImode);
25353 emit_insn (gen_popcntbdi2 (tmp1, src));
25355 tmp2 = gen_reg_rtx (DImode);
25356 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25357 tmp3 = gen_reg_rtx (DImode);
25358 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25360 tmp4 = gen_reg_rtx (DImode);
25361 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25362 tmp5 = gen_reg_rtx (DImode);
25363 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25365 tmp6 = gen_reg_rtx (DImode);
25366 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25367 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25370 rs6000_emit_popcount (tmp, src);
25371 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25375 /* Return an RTX representing where to find the function value of a
25376 function returning MODE. */
25378 rs6000_complex_function_value (enum machine_mode mode)
25380 unsigned int regno;
25382 enum machine_mode inner = GET_MODE_INNER (mode);
25383 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25385 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25386 regno = FP_ARG_RETURN;
25389 regno = GP_ARG_RETURN;
25391 /* 32-bit is OK since it'll go in r3/r4. */
25392 if (TARGET_32BIT && inner_bytes >= 4)
25393 return gen_rtx_REG (mode, regno);
25396 if (inner_bytes >= 8)
25397 return gen_rtx_REG (mode, regno);
25399 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25401 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25402 GEN_INT (inner_bytes));
25403 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25406 /* Target hook for TARGET_FUNCTION_VALUE.
25408 On the SPE, both FPs and vectors are returned in r3.
25410 On RS/6000 an integer value is in r3 and a floating-point value is in
25411 fp1, unless -msoft-float. */
25414 rs6000_function_value (const_tree valtype,
25415 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25416 bool outgoing ATTRIBUTE_UNUSED)
25418 enum machine_mode mode;
25419 unsigned int regno;
25421 /* Special handling for structs in darwin64. */
25422 if (rs6000_darwin64_abi
25423 && TYPE_MODE (valtype) == BLKmode
25424 && TREE_CODE (valtype) == RECORD_TYPE
25425 && int_size_in_bytes (valtype) > 0)
25427 CUMULATIVE_ARGS valcum;
25431 valcum.fregno = FP_ARG_MIN_REG;
25432 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25433 /* Do a trial code generation as if this were going to be passed as
25434 an argument; if any part goes in memory, we return NULL. */
25435 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25438 /* Otherwise fall through to standard ABI rules. */
25441 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25443 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25444 return gen_rtx_PARALLEL (DImode,
25446 gen_rtx_EXPR_LIST (VOIDmode,
25447 gen_rtx_REG (SImode, GP_ARG_RETURN),
25449 gen_rtx_EXPR_LIST (VOIDmode,
25450 gen_rtx_REG (SImode,
25451 GP_ARG_RETURN + 1),
25454 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25456 return gen_rtx_PARALLEL (DCmode,
25458 gen_rtx_EXPR_LIST (VOIDmode,
25459 gen_rtx_REG (SImode, GP_ARG_RETURN),
25461 gen_rtx_EXPR_LIST (VOIDmode,
25462 gen_rtx_REG (SImode,
25463 GP_ARG_RETURN + 1),
25465 gen_rtx_EXPR_LIST (VOIDmode,
25466 gen_rtx_REG (SImode,
25467 GP_ARG_RETURN + 2),
25469 gen_rtx_EXPR_LIST (VOIDmode,
25470 gen_rtx_REG (SImode,
25471 GP_ARG_RETURN + 3),
25475 mode = TYPE_MODE (valtype);
25476 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25477 || POINTER_TYPE_P (valtype))
25478 mode = TARGET_32BIT ? SImode : DImode;
25480 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25481 /* _Decimal128 must use an even/odd register pair. */
25482 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25483 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25484 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25485 regno = FP_ARG_RETURN;
25486 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25487 && targetm.calls.split_complex_arg)
25488 return rs6000_complex_function_value (mode);
25489 else if (TREE_CODE (valtype) == VECTOR_TYPE
25490 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25491 && ALTIVEC_VECTOR_MODE (mode))
25492 regno = ALTIVEC_ARG_RETURN;
25493 else if (TREE_CODE (valtype) == VECTOR_TYPE
25494 && TARGET_VSX && TARGET_ALTIVEC_ABI
25495 && VSX_VECTOR_MODE (mode))
25496 regno = ALTIVEC_ARG_RETURN;
25497 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25498 && (mode == DFmode || mode == DCmode
25499 || mode == TFmode || mode == TCmode))
25500 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25502 regno = GP_ARG_RETURN;
25504 return gen_rtx_REG (mode, regno);
25507 /* Define how to find the value returned by a library function
25508 assuming the value has mode MODE. */
25510 rs6000_libcall_value (enum machine_mode mode)
25512 unsigned int regno;
25514 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25516 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25517 return gen_rtx_PARALLEL (DImode,
25519 gen_rtx_EXPR_LIST (VOIDmode,
25520 gen_rtx_REG (SImode, GP_ARG_RETURN),
25522 gen_rtx_EXPR_LIST (VOIDmode,
25523 gen_rtx_REG (SImode,
25524 GP_ARG_RETURN + 1),
25528 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25529 /* _Decimal128 must use an even/odd register pair. */
25530 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25531 else if (SCALAR_FLOAT_MODE_P (mode)
25532 && TARGET_HARD_FLOAT && TARGET_FPRS
25533 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25534 regno = FP_ARG_RETURN;
25535 else if (ALTIVEC_VECTOR_MODE (mode)
25536 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25537 regno = ALTIVEC_ARG_RETURN;
25538 else if (VSX_VECTOR_MODE (mode)
25539 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25540 regno = ALTIVEC_ARG_RETURN;
25541 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25542 return rs6000_complex_function_value (mode);
25543 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25544 && (mode == DFmode || mode == DCmode
25545 || mode == TFmode || mode == TCmode))
25546 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25548 regno = GP_ARG_RETURN;
25550 return gen_rtx_REG (mode, regno);
25554 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25555 Frame pointer elimination is automatically handled.
25557 For the RS/6000, if frame pointer elimination is being done, we would like
25558 to convert ap into fp, not sp.
25560 We need r30 if -mminimal-toc was specified, and there are constant pool
25564 rs6000_can_eliminate (const int from, const int to)
25566 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25567 ? ! frame_pointer_needed
25568 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25569 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25573 /* Define the offset between two registers, FROM to be eliminated and its
25574 replacement TO, at the start of a routine. */
25576 rs6000_initial_elimination_offset (int from, int to)
25578 rs6000_stack_t *info = rs6000_stack_info ();
25579 HOST_WIDE_INT offset;
25581 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25582 offset = info->push_p ? 0 : -info->total_size;
25583 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25585 offset = info->push_p ? 0 : -info->total_size;
25586 if (FRAME_GROWS_DOWNWARD)
25587 offset += info->fixed_size + info->vars_size + info->parm_size;
25589 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25590 offset = FRAME_GROWS_DOWNWARD
25591 ? info->fixed_size + info->vars_size + info->parm_size
25593 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25594 offset = info->total_size;
25595 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25596 offset = info->push_p ? info->total_size : 0;
25597 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25600 gcc_unreachable ();
25606 rs6000_dwarf_register_span (rtx reg)
25610 unsigned regno = REGNO (reg);
25611 enum machine_mode mode = GET_MODE (reg);
25615 && (SPE_VECTOR_MODE (GET_MODE (reg))
25616 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25617 && mode != SFmode && mode != SDmode && mode != SCmode)))
25622 regno = REGNO (reg);
25624 /* The duality of the SPE register size wreaks all kinds of havoc.
25625 This is a way of distinguishing r0 in 32-bits from r0 in
25627 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25628 gcc_assert (words <= 4);
25629 for (i = 0; i < words; i++, regno++)
25631 if (BYTES_BIG_ENDIAN)
25633 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25634 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25638 parts[2 * i] = gen_rtx_REG (SImode, regno);
25639 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25643 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25646 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25649 rs6000_init_dwarf_reg_sizes_extra (tree address)
25654 enum machine_mode mode = TYPE_MODE (char_type_node);
25655 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25656 rtx mem = gen_rtx_MEM (BLKmode, addr);
25657 rtx value = gen_int_mode (4, mode);
25659 for (i = 1201; i < 1232; i++)
25661 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25662 HOST_WIDE_INT offset
25663 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25665 emit_move_insn (adjust_address (mem, mode, offset), value);
25670 /* Map internal gcc register numbers to DWARF2 register numbers. */
25673 rs6000_dbx_register_number (unsigned int regno)
25675 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25677 if (regno == MQ_REGNO)
25679 if (regno == LR_REGNO)
25681 if (regno == CTR_REGNO)
25683 if (CR_REGNO_P (regno))
25684 return regno - CR0_REGNO + 86;
25685 if (regno == XER_REGNO)
25687 if (ALTIVEC_REGNO_P (regno))
25688 return regno - FIRST_ALTIVEC_REGNO + 1124;
25689 if (regno == VRSAVE_REGNO)
25691 if (regno == VSCR_REGNO)
25693 if (regno == SPE_ACC_REGNO)
25695 if (regno == SPEFSCR_REGNO)
25697 /* SPE high reg number. We get these values of regno from
25698 rs6000_dwarf_register_span. */
25699 gcc_assert (regno >= 1200 && regno < 1232);
25703 /* target hook eh_return_filter_mode */
25704 static enum machine_mode
25705 rs6000_eh_return_filter_mode (void)
25707 return TARGET_32BIT ? SImode : word_mode;
25710 /* Target hook for scalar_mode_supported_p. */
25712 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25714 if (DECIMAL_FLOAT_MODE_P (mode))
25715 return default_decimal_float_supported_p ();
25717 return default_scalar_mode_supported_p (mode);
25720 /* Target hook for vector_mode_supported_p. */
25722 rs6000_vector_mode_supported_p (enum machine_mode mode)
25725 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25728 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25731 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25738 /* Target hook for invalid_arg_for_unprototyped_fn. */
25739 static const char *
25740 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25742 return (!rs6000_darwin64_abi
25744 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25745 && (funcdecl == NULL_TREE
25746 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25747 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25748 ? N_("AltiVec argument passed to unprototyped function")
25752 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25753 setup by using __stack_chk_fail_local hidden function instead of
25754 calling __stack_chk_fail directly. Otherwise it is better to call
25755 __stack_chk_fail directly. */
25758 rs6000_stack_protect_fail (void)
25760 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25761 ? default_hidden_stack_protect_fail ()
25762 : default_external_stack_protect_fail ();
25766 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25767 int num_operands ATTRIBUTE_UNUSED)
25769 if (rs6000_warn_cell_microcode)
25772 int insn_code_number = recog_memoized (insn);
25773 location_t location = locator_location (INSN_LOCATOR (insn));
25775 /* Punt on insns we cannot recognize. */
25776 if (insn_code_number < 0)
25779 temp = get_insn_template (insn_code_number, insn);
25781 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25782 warning_at (location, OPT_mwarn_cell_microcode,
25783 "emitting microcode insn %s\t[%s] #%d",
25784 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25785 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25786 warning_at (location, OPT_mwarn_cell_microcode,
25787 "emitting conditional microcode insn %s\t[%s] #%d",
25788 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25792 #include "gt-rs6000.h"